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

Solution 1:

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.

Solution 2:

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