好吧,其实我是标题党来的…
一篇解决实际问题的文章,顺便带你认识下一些Linux的命令以及简单的shell脚本编程…
系统版本:Ubuntu 18.04.4 LTS
我的笔记本电脑外接了一个显示器,本来以为和Windows下一样,笔记本显示器和外接显示器会同步显示,结果ubuntu下外接显示器和笔记本显示不一致,感觉像是被强制分屏了。体验非常不好,感觉还影响了I/O设备,把外接显示器拔了结果鼠标和键盘都不太能动了,重启在没外接显示器的前提下鼠标和键盘才恢复正常。
输入xrandr命令查看当前的显示设备:
xrandr
xrandr简介: "xrandr" 是一款官方的 RandR (Resize and Rotate)Wikipedia:X Window System 扩展配置工具。它可以设置屏幕显示的大小、方向、镜像等。
发现有两个显示设备,如下图:
一个是eDP-1(笔记本显示器),一个是HDMI-1(外接显示器),于是用以下命令关闭了笔记本的显示器,只用外接显示器
xrandr --output HDMI-1 --auto --output eDP-1 --off
解释: xrandr --output 要显示的设备 --auto --output 要关闭的设备 --off
这样舒服多了,但是一重启,发现又回到原来的样子,要再次手动使用以上命令…
每次开机都要这么手动输一次命令才能关掉笔记本的显示器,当然不爽啦,于是就想能不能在开机的时候让系统自己跑个脚本运行这个命令。
怎么自动执行这个命令呢?当然想到了shell脚本啦。只要能在shell脚本中实现我们要做的事情,然后让linux开机自动运行shell脚本,不必每次开机都要手动输入命令才能关闭笔记本显示器只显示外接显示器,就达到了我的目的。
所以我们需要做到两件事情,一是我们需要让脚本在开机时能自动运行,二是我们需要写一个可以执行关闭显示器命令的脚本
想做到让Linux开机运行某个任务有几种方式,这里我用了crontab命令。
通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。
为了确保用crontab可以执行到我们的脚本,我们在某个路径下新建脚本authxrandr.sh,比如在/home/pipi/myshell下新建authxrandr.sh
然后写入最简单的几行:
#! /bin/bash
echo "exec scripts success" >>/home/pipi/myshell/crontablog.txt
exit 0
解释:
1)#! /bin/bash
声明这个脚本使用的shell名称,当这个程序执行时,它能够加载bash的相关环境配置文件,并且执行bash使得命令能够执行,如果没有设置好这一行,那系统可能会因为无法判断该程序需要使用什么shell来执行而导致该程序无法执行。
2)echo “exec scripts success” >>/home/pipi/myshell/crontablog.txt
输出exec scripts success这句话到crontablog.tx文件中去,>>表示在文件后追加,如果文件不存在会自动创建。
这个脚本的主要目的是为了验证我们的shell脚本是否被执行到。执行前我们需要用chmod命令赋予文件执行权限:
chmod +x /home/pipi/myshell/authxrandr.sh
然后使用./authxrandr.sh执行脚本,结果发现文件crontablog.txt成功追加一行exec scripts success
,说明我们的脚本可以正常执行。
解释:
使用ls -l 以下命令可以查看文件权限等信息,其中r为可读,w为可写,x为可执行
ls -l /home/pipi/myshell/autoxrandr.sh
如果新建文件对当前用户没有可执行权限(x),直接使用./authxrandr.sh就会出现下面的报错:
注意:
这里最好要先验证你的脚本是否有问题,至少需要用ls -l检查下是否有执行权限
接下来我们用crontab -e 编辑当前用户的时程表,首次打开编辑可能会让你选择用哪个编辑器,可以选择nano(最简单)或者vi进入。
我们在打开的文件里面加入这么一句:
@reboot /home/pipi/myshell/autoxrandr.sh
表示系统重启时执行脚本autoxrandr.sh。
保存退出后重启电脑验证一下,如果重启后你发现/home/pipi/myshell/crontablog.txt 多了一行
exec scripts success
那么说明我们成功的用crontab实现了系统重启后执行我们编写的shell脚本autoxrandr.sh。
经过一番研究,参考了国外一些Linux问答社区的回答, 新的authxrandr.sh修改如下:
#! /bin/bash
export DISPLAY=:0
echo "start run scripts" >>/home/pipi/myshell/crontablog.txt
# wait until user signs on to get .Xauthority file settings.
UserName=""
while [[ $UserName == "" ]]; do
sleep 2
echo "waiting for user login" > /home/pipi/myshell/crontablog.txt
UserName="$(who -u | grep -F '(:0)' | head -n 1 | awk '{print $1}')"
done
sleep 10
xrandr --output HDMI-1 --auto --output eDP-1 --off
exit 0
解释:
这个脚本做了几件事情:
1)export DISPLAY=:0,设置当前用户的图形显示的位置(当前机器),这是因为cron默认的环境变量设置不包括这个$DISPLAY;
Cron provides limited set of environment variables by default . To get xrandr to work through a Cron job, you should export the value of the current user’s $DISPLAY variable . To do that add the follow line to the beginning of your script (or add it within the crontab file )
2)等待用户登录;
之所以要等待用户登录完再执行关闭显示器操作的原因是系统需要时间寻找外接显示器信号,否则找不到显示器会导致我们的命令失败,所以我们等待用户登录完再去执行关闭笔记本显示器的命令;
3)xrandr 设置图形输出到外接显示器HDMI-1,关闭显示器eDP-1;
4)用echo输出一些字符串到文件中,可以通过查看/home/pipi/myshell/crontablog.txt 验证我们的程序是否执行到。
重启验证下,登录后成功关闭了笔记本的显示器!
1、xrandr简介:https://wiki.archlinux.org/index.php/Xrandr_%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87
2、crontab的简介和例子:
https://www.runoob.com/linux/linux-comm-crontab.html
3、chmod用于修改文件权限
4、ls -l 文件名
可以详细列举文件的权限等信息
5、export
用于设置或显示环境变量
https://www.runoob.com/linux/linux-comm-export.html
6、shell编程相关
1)#! /bin/bash
声明这个脚本使用的shell名称,当这个程序执行时,它能够加载bash的相关环境配置文件,并且执行bash使得命令能够执行,如果没有设置好这一行,那系统可能会因为无法判断该程序需要使用什么shell来执行而导致该程序无法执行。
2)如果新建文件对当前用户没有可执行权限(x),直接使用./authxrandr.sh就会出现下面的报错:
Permission denied
7、参考链接:
1)国外问答社区类似的问题
https://askubuntu.com/questions/1102389/xrandr-not-working-on-crontab
2)为什么要添加export DISPLAY=:0
https://askubuntu.com/questions/958228/adjust-brightness-with-xrandr-and-cron-job)