Shell问题随记
脚本实现切换用户后操作
问题描述:shell脚本中如果涉及切换用户,无法执行切换操作之后命令,如root用户执行以下脚本:
问题原因:脚本中切换用户后,会先开一个子shell,所以后续命令不会执行,返回当前shell后才会执行
解决方案:使用xdotool模仿键盘输入,可规避环境问题,安装xdotool(apt install xdotool)后,修改代码如下:
补充:xdotool存在一些稳定性问题,以上方案实测仅方案3可用,其他方案理论上无问题,但执行失败,常用命令说明:
通过命令创建用户并设置密码
问题描述:shell脚本使用root用户创建普通用户并设置密码操作时,因为设置密码是交互式操作,需要用户2次确认,使用echo Test#136 | passwd login_a显然不会成功。
解决方案:使用非交互式命令设置密码,如下:
补充:如果密码中包含 $ 字符,需要使用反斜线进行转义\$
账号相关命令
用户管理
解除账户锁定
问题描述:命令行输出错误密码次数过多,导致账号被锁定xmin
解决办法:
ssh配置root登录
问题描述:ssh默认不允许root用户登录
解决办法:
删除目录的非指定文件
问题描述 在shell 脚本调试或者执行时,会经常遇到需要删除当前目录不需要的文件,手动删除十分麻烦。
解决方案
shopt -s extglob
rm -rf !(file1|file2)
解决过程与分析
shopt 命令用于显示和设置shell中的行为选项,通过这些选项以增强shell易用性;如果不执行shopt -s extglob ,直接执行 rm -rf !(*.txt)会提示bash: !: event not found
实例:
1) 在/home/amd目录下存在文件:1.txt、test.log、test.txt、1.deb、1.log,现在只保留txt格式的文件。
补充代码块
2) 在/home/amd目录下存在文件:1.txt、test.log、test.txt、1.deb、1.log,现在只保留txt和deb格式的文件。
补充代码块
3) 在/home/amd目录下存在文件:1.txt、test.log、test.txt、1.deb、1.log,现在保留指定目录下log格式的文件。
补充代码块
shell中单/双/反引号的区别
问题描述 在shell执行的时候,常常遇到调用的变量被当做字符处理,导致脚本运行出错。
解决方案 使用双引号将需要保留特殊字符的字符串括起来。
解决过程与分析 双引号(""):保留特殊字符的功能,如美元符号、反引号、反斜线。 单引号(''):被单引号括起来的字符都被视为普通字符对待。 反引号(``):被反引号括起来的字符串被当做shell命令执行,其标准输入结果取代整个反引号部分。
实例:
补充代码块
杀死进程的多种方法
问题描述 在shell脚本执行中,经常遇到需要终止某个进程,但是通过进程id终止十分不方便,因为每次执行的进程id是变化的,导致脚本运行效率低下。
解决方案
第一种:ps aux | grep netserver | grep -v grep | cut -c 9-15 | xargs kill -9
第二种:pidof netserver | xargs kill -9
第三种:pgrep netserver | xargs kill -9
解决过程与分析
第一种:
ps aux 显示所有的进程
grep netserver 过滤显示netserver相关的进程
grep -v grep 过滤grep的查询进程
cut -c 9-15 截取对应位置的字符,即进程id
xargs 捕获左边的输出传递给右边的命令
kill -9 强制杀死进程
第二种:
pidof 用于查找指定名称的进程的进程号id号
语法:
pidof (选项) (参数)
选项:
-s:仅返回一个进程号;
-c:仅显示具有相同“root”目录的进程;
-x:显示由脚本开启的进程;
-o:指定不显示的进程ID。
第三种:
pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行。
语法:
pgrep (选项) (参数)
选项:
-l 同时显示进程名和PID
-o 当匹配多个进程时,显示进程号最小的那个
-n 当匹配多个进程时,显示进程号最大的那个
实例:
-
启动stress进程,执行命令: stress -c 1 & stress -c 1 & stress -c 1 &
-
使用第一种终止进程的命令:
ps aux | grep stress | grep -v grep | cut -c 9-15 | xargs kill -9 -
使用第二种终止进程的命令:
pidof stress | xargs kill -9 -
使用第三种终止进程的命令:
pgrep stress | xargs kill -9
$#,$0,$@ 等用法及说明
问题描述
在编写shell脚本的时候常常会向方法里面传递不同的参数,将参数放入变量的方式会导致脚本行数增加,代码执行效率不高,且不利于后期维护。
解决方案
使用$1、$2、$@等方式调用传入的参数。
解决过程与分析
实例:
创建脚本文件:test.sh,将下面的代码复制到文件中。
