如何在Unity中通过命令行更改桌面背景?

我有一个脚本,每天都会用NASA APOD更新我的桌面背景。自从升级到11.10以后,那个脚本就停止工作了,可能是因为我在使用gconftool-2来实际更新桌面背景。在Unity下有没有新的方法来做这个?
6个回答

Gnome Shell(Gnome 3)现在使用GSettings而不是GConf。因此,在Gnome Shell中,您可以使用命令行工具gsettings来进行操作。与gconftool类似,它允许您获取或设置单个键。
您可以按以下方式获取当前背景图像的URI:
gsettings get org.gnome.desktop.background picture-uri
'file:///home/serrano/Pictures/x.jpg'

将背景URI设置为以下内容(这将立即更新您的桌面背景):
gsettings set org.gnome.desktop.background picture-uri file:///home/serrano/Pictures/y.jpg

请注意,为了使其正常工作(与 gconftool 不同),您必须在 URI 前加上 "file://"。 Ubuntu 22.04 及更高版本 自 Ubuntu 22.04 起,行为有所改变,具体取决于您的颜色方案偏好。
gsettings get org.gnome.desktop.interface color-scheme

如果你的color-scheme是"prefer-dark",请使用picture-uri-dark代替:
gsettings set org.gnome.desktop.background picture-uri-dark file:///home/serrano/Pictures/y.jpg

否则像以前一样使用picture-uri
gsettings set org.gnome.desktop.background picture-uri file:///home/serrano/Pictures/y.jpg

我在Ubuntu 12.04中使用了这个命令,结果系统崩溃了。 - user25165
4@YumYumYum:除非您的系统发生其他问题,否则上述命令很少会导致系统崩溃。 - Serrano Pereira
你可以使用gsettings将Cinnamon添加到桌面环境列表中 ;) - MrVaykadji
请注意,为了使其正常工作(与gconftool不同),您必须在URI前加上"file://"。这非常重要!我没有在其他任何地方找到明确提到此事。 - Tom
3这对于当前登录的用户来说很好。我想知道如何以编程方式更改另一个用户的壁纸!我尝试过sudo --user=<username> gsettings ...但失败了。 - kaiwan
我可以给它添加一种淡入的过渡效果吗? - akxer
有没有办法告诉gsettings如何显示图片?比如说是否应该拉伸以适应屏幕或其他方式? - Alexej Magura

这段代码会随机更换给定目录中的壁纸。
#!/bin/bash

DIR="/home/indra/Pictures/wallpapers"
PIC=$(ls $DIR/* | shuf -n1)
gsettings set org.gnome.desktop.background picture-uri "file://$PIC"

保存此脚本并使用命令“crontab -e”进行编辑(它启动一个编辑器,在文件末尾放置此行):

*/1     *     *     *     *         /bin/bash /path/to/script.sh

1壁纸目录必须只包含壁纸文件,不能包含任何目录。 - loxaxs
gsettings不能在cron中运行。 但是,您需要设置DBUS_SESSION_BUS_ADDRESS环境变量,以便gsettings工作。 您可以通过在gsettings之前添加这两行(使用分号分隔的行)来实现:PID=$(pgrep gnome-session); export DBUS_SESSION_BUS_ADDRESS = $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ | cut -d= -f2-); - willbradley

介绍

这个答案是对原始答案的修改。随着我在Ubuntu和Linux学习中的进步,我发现了各种不同的方法,并加深了我对在Ubuntu中设置背景的理解。这个答案是我尽量详细记录我迄今为止所学到的知识的尝试,希望这些材料对他人有所帮助。

重要的部分是,要通过命令行设置Unity桌面的背景,你可以使用

gsettings set org.gnome.desktop.background picture-uri 'file:///home/JohnDoe/Pictures/cool_wallpaper.jpg'

在Unity和裸露的X桌面中设置背景

Unity的工作方式是,在底下是裸露的X桌面,上面是Unity的桌面窗口(实际上是Ubuntu默认文件管理器Nautilus窗口的特殊实例)。因此,当你调用

gsettings set org.gnome.desktop.background picture-uri 'file:///home/JohnDoe/Pictures/cool_wallpaper.jpg'

设置特殊的鹦鹉螺窗口的背景。当您禁用桌面图标时,
gsettings set org.gnome.desktop.background show-desktop-icons false

这将关闭Nautilus桌面并显示一个简化的X桌面。对于简化的X桌面,您可以使用feh程序。特别是这个命令:
feh --bg-scale /home/JohnDoe/Pictures/cool_wallpaper.jpg

还有一个图形用户界面的替代方案,叫做"nitrogen"。"feh"和"nitrogen"这两种方法可以用于除了Unity之外的其他桌面环境,比如"openbox"或"blackbox"。"gsettings"方法可以用于Unity或其他基于GNOME的桌面环境。
解析"gsettings"命令
"gsettings"命令到底是做什么的呢?首先,每个用户都有一个dconf设置数据库,它被设计为GConf的替代品,并且可以通过"dconf"命令或"gsettings"命令访问。在这里,我们主要涉及到"org.gnome.desktop.background"模式和它的一个键,即"picture-uri"。

URI,那个file:///home/JohnDoe/Pictures/cool_wallpaper.png,其实代表的是统一资源标识符,最初是为互联网使用而创建的,但这里有一个文件URI方案,就是我们在这里看到的。URI的酷之处在于,如果您使用非英语环境,则会给出字节编码路径,例如在我的中文桌面上,我有以下背景的URI:'file:///home/xieerqi/%E5%9B%BE%E7%89%87/Wallpapers/moon_moon.jpg'

使用gsettings进行脚本编写

当然了,每次都写出命令是很繁琐的,可以使用一些脚本魔法来简化。例如,这是我在~/.bashrc中设置的内容,以便我可以随意更改背景:

change_background() {
    FILE="'file://$(readlink -e "$1" )'" 
    if [ "$FILE" != "'file://'" ] 
    then
        gsettings set org.gnome.desktop.background picture-uri "$FILE" 
    else
        echo "File doesn't exist" 
    fi 
} 

这个函数可以使用绝对路径来调用,例如:
change_background /home/JohnDoe/Pictures/cool_wallpaper.jpg

或者使用相对路径从当前工作目录开始

change_background Pictures/cool_wallpaper.jpg

它还会检查文件是否存在并解析符号链接。这可以用于Shell脚本或作为独立函数进行日常使用。
当然,这不是唯一的方法。Python有一个用于Gio的API(这是gsettings背后的主要库)。我写了gsettings_getgsettings_set函数,对其他项目非常有用,比如Launcher List Indicator。在设置背景时也可以使用它,并且我最近刚刚在this question中使用过它。这是同样方法的简化版本:
#!/usr/bin/env python3
"""
Author: Serg Kolo , <1047481448@qq.com>
Date: December, 21,2016
Purpose: script for setting wallpaper, the pythonic way
Written for: https://askubuntu.com/q/66914/295286
"""
from gi.repository import Gio
import os,sys,random

def gsettings_set(schema, path, key, value):
    """Set value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema, path)
    if isinstance(value, list):
        return gsettings.set_strv(key, value)
    if isinstance(value, int):
        return gsettings.set_int(key, value)
    if isinstance(value,str): 
        return gsettings.set_string(key,value)

def error_and_exit(message):
    sys.stderr.write(message + "\n")
    sys.exit(1)

def main():
    gschema='org.gnome.desktop.background'
    key='picture-uri'
    if len(sys.argv) != 2:
        error_and_exit('>>> Path to a file is required')
    if not os.path.isfile(sys.argv[1]):
        error_and_exit('>>> Path "' + sys.argv[1] + \
                       '" isn\'t a file or file doesn\'t exit')
    full_path = os.path.abspath(sys.argv[1])
    uri = Gio.File.new_for_path(full_path).get_uri()
    gsettings_set(gschema,None,key,uri)


if __name__ == '__main__': main()

当然,脚本的规则在这里也适用:确保使用chmod +x set_wallpaper.py命令使其可执行,并将其存储在(最好是)~/bin文件夹中。使用方法很简单:./set_wallpaper.py Picture/cool_image.py。此脚本的源代码也可以在我的GitHub存储库中找到,其中还有许多其他脚本。

在Ubuntu 22.04中,有两个不同的图像/命令用于浅色和深色主题:
深色主题(picture-uri-dark):
gsettings set org.gnome.desktop.background picture-uri-dark file:///home/Pictures/image.jpg

亮色主题(图片链接):

gsettings set org.gnome.desktop.background picture-uri file:///home/Pictures/image.jpg

此外,您还可以使用这个:
dconf write "/org/gnome/desktop/background/picture-uri" "'file:///home/YOUR_USER/bg.png'"

在Ubuntu 21.04上,写入/org/gnome/desktop/background/picture-uri会强制重绘/更新所有GUI应用程序。使用dconf不会干扰其他应用程序。 - zupet

感谢Serrano的精彩回答,我能够编写这个脚本,并将其作为我新机器设置脚本的一部分来设置黑色背景。
#! /bin/bash
SRC_URI="https://i.imgur.com/uomkVIL.png"
FNAME="/home/$USER/Pictures/black.png"
wget "$SRC_URI" -O "$FNAME"
gsettings set org.gnome.desktop.background picture-uri "$FNAME"