How can I create a new profile for Gnome terminal via command line?

For Gnome-Terminal < 3.8

You can not create a new profile, but you can dump your current configuration, using gconftool-2, modify it and load it.

gconftool-2 --dump '/apps/gnome-terminal' > gnome-terminal-conf.xml
## Modify the file here.
gconftool-2 --load gnome-terminal-conf.xml

Remember that it only returns the non-default values (or what gconf detects as non-default) so, the resultant file could not be complete.


For GNOME Terminal >= 3.8, to create/edit/read profiles through cli, you can use either dconf-cli or gsettings. My choice is dconf-cli.

The dconf directory of GNOME Terminal is /org/gnome/terminal/legacy/profiles:. All operations happen in this dir. I store it in $dconfdir which is shown in the scripts below.

Create a new profile

Minimum steps are

  1. Generate a UUID for the profile by running command uuidgen
  2. Append it to list: dconf write "$dconfdir/list" "[..., 'UUID']"
  3. Set its visible-name: dconf write "$dconfdir/:UUID"/visible-name "'NAME'"

After that, even if many settings are not set, a new profile will show up in Terminal's GUI settings so that you can edit settings through GUI.

A working script:

#!/bin/bash
dconfdir=/org/gnome/terminal/legacy/profiles:

create_new_profile() {
    local profile_ids=($(dconf list $dconfdir/ | grep ^: |\
                        sed 's/\///g' | sed 's/://g'))
    local profile_name="$1"
    local profile_ids_old="$(dconf read "$dconfdir"/list | tr -d "]")"
    local profile_id="$(uuidgen)"

    [ -z "$profile_ids_old" ] && local profile_ids_old="["  # if there's no `list` key
    [ ${#profile_ids[@]} -gt 0 ] && local delimiter=,  # if the list is empty
    dconf write $dconfdir/list \
        "${profile_ids_old}${delimiter} '$profile_id']"
    dconf write "$dconfdir/:$profile_id"/visible-name "'$profile_name'"
    echo $profile_id
}

# Create profile
id=$(create_new_profile TEST)

Be careful about the quotes around the value you write. As said in the manual,

When setting a key, you also need specify a VALUE. The format for the value is that of a serialized GVariant, so e.g. a string must include explicit quotes: "'foo'". This format is also used when printing out values.

You can set more options of the profile through cli if you want. Run

dconf write /org/gnome/terminal/legacy/profiles:/:UUID/KEY "'NAME'"

to set. You can use dconf-editor to check avaliable options. Navigate to a path like /org/gnome/terminal/legacy/profiles:/:9ca4ab84-42f2-4acf-8aa9-50e6351b209a/. It'd be better to check an old profile which has many options set.

Duplicate a profile

You can dconf dump an old profile and load it to an existing one. So to duplicate a profile, you need to create a new one using the steps above, and copy an old one's profile to override it. Remember to rename it after overriding.

A working script:

# ... codes from last script

in_array() {
  local e
  for e in "${@:2}"; do [[ $e == $1 ]] && return 0; done
  return 1
}

duplicate_profile() {
    local from_profile_id="$1"; shift
    local to_profile_name="$1"; shift
    local profile_ids=($(dconf list $dconfdir/ | grep ^: |\
                        sed 's/\///g' | sed 's/://g'))

    # If UUID doesn't exist, abort
    in_array "$from_profile_id" "${profile_ids[@]}" || return 1
    # Create a new profile
    local id=$(create_new_profile "$to_profile_name")
    # Copy an old profile and write it to the new
    dconf dump "$dconfdir/:$from_profile_id/" \
        | dconf load "$dconfdir/:$id/"
    # Rename
    dconf write "$dconfdir/:$id"/visible-name "'$to_profile_name'"
}

# Create a profile from an existing one
duplicate_profile $id TEST1

To get a profile's UUID by its name:

get_profile_uuid() {
    # Print the UUID linked to the profile name sent in parameter
    local profile_ids=($(dconf list $dconfdir/ | grep ^: |\
                        sed 's/\///g' | sed 's/://g'))
    local profile_name="$1"
    for i in ${!profile_ids[*]}; do
        if [[ "$(dconf read $dconfdir/:${profile_ids[i]}/visible-name)" == \
            "'$profile_name'" ]]; then
            echo "${profile_ids[i]}"
            return 0
        fi
    done
}

id=$(get_profile_uuid Default)

Set a profile as default

Simply write the UUID of the profile to the key default:

dconf write $dconfdir/default "'$UUID'"

Reference

  • Anthony25/gnome-terminal-colors-solarized. I figure out my way by reading a lot of codes from here. Really helpful.
  • dconf Reference Manual

# find out how many pofiles there are - at the beginning there will be just 1 - Default
profiles_list=$(gconftool-2 --get "/apps/gnome-terminal/global/profile_list" | sed "s|\[||;s|\]||;")
echo "1 Profiles List: " ${profiles_list}
last_profile=$(echo "${profiles_list}" | sed "s/^.*,//" | sed 's/Profile//')
echo "Last Profile Name/Number: " ${last_profile}

# set the "ProfileX" X number to 0 if only default is there or whatever the last is plus 1
if [ ${last_profile} == "Default" ]; then
    next_profile_number=0;
echo "1 New Profile Number: " ${next_profile_number}
else
    next_profile_number=$(( ${last_profile} + 1 ));
echo "2 New Profile Number: " ${next_profile_number}
fi
echo "New Profile Number: " ${next_profile_number}

# construct profiles list with extra profile "number"
profiles_list=$(echo "[${profiles_list},Profile${next_profile_number}]")
echo "1 Profiles List: " ${profiles_list}

# get a dump of the default profile, change global name to the new profile name
profileName=MyNewProfile
gconftool-2 --dump "/apps/gnome-terminal/profiles/Default" > /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml
sed -i "s|Default|Profile${next_profile_number}|g" /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

# load new profile
gconftool-2 --load /tmp/${USER}_gnome-terminal_profiles_${profileName}.xml

# tell gnome-terminal that is has another profile
gconftool-2 --set --type list --list-type string "/apps/gnome-terminal/global/profile_list" "${profiles_list}"

# set properties
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/visible_name "${profileName}"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/exit_action "hold"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/font "Monospace 14"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/background_color "#000000000000"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/foreground_color "#0000FFFF0000"
gconftool-2 --set --type string /apps/gnome-terminal/profiles/Profile${next_profile_number}/scrollbar_position "hidden"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/use_system_font "false"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/use_theme_colors "false"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/login_shell "true"
gconftool-2 --set --type boolean /apps/gnome-terminal/profiles/Profile${next_profile_number}/scrollback_unlimited "true"

# create a terminal
gnome-terminal --geometry=80x24+0+0 --profile=${profileName} title "${profileName}" --zoom 0.8 -e "/bin/sh"