日常写Shell脚本或者敲命令,常用内置命令整理,这些命令不用创建子进程,比外部命令快,按真实场景分好用。
export是给子进程传环境变量的,子shell能继承,反过来不行。
# 把当前变量导出为环境变量,子进程能用
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
# 不带参数查看所有已导出的环境变量
export
子shell改了导出的变量,父shell不会变;如果要在当前shell生效并传给下一个,直接export就行,不用先赋值再export。
readonly把变量设为只读,防止误改,脚本里常用存固定配置。
# 把变量设为只读
readonly MAX_COUNT=10
# 查看所有只读变量
readonly
只读变量不能unset,不能改值。
set/env/unset配合用,区分不同范围的变量。
# set显示所有shell变量(包括未导出的)和函数
set
# env只显示环境变量
env
# 取消设置变量,不管是shell变量还是环境变量
unset MAX_COUNT
export、env、set设的变量都能用unset清,但只读的不行。
echo除了普通输出,还常用来查看上一条命令的退出码。
# 普通输出字符串,加引号防空格和特殊字符
echo "hello shell"
# 输出上一条命令的退出码,0成功非0失败
echo $?
不加引号的话,多个空格会被合并成一个。
read从标准输入读内容给变量,加-p有提示更友好。
# 带提示读一行
read -p "请输入用户名:" USERNAME
echo "你输入的是:$USERNAME"
一次读多个变量,空格分隔输入就行。
eval执行拼接好的命令,或者动态生成变量名,别随便用用户输入的内容,容易有安全风险。
# 执行变量里存的命令
CMD="ls -alh"
eval $CMD
# 动态生成变量名并赋值
KEY="NAME"
VALUE="zhangsan"
eval "$KEY=$VALUE"
echo $NAME
exec替换当前shell进程为指定命令,执行完后当前shell直接退出,脚本里后面的代码不会跑。
# 替换当前shell为ls,执行完ls就退出
exec ls -alh
exit退出当前脚本,指定返回码,父进程能通过$?拿到结果。
# 成功退出
exit 0
# 出错退出,返回1
exit 1
shift处理脚本的多个位置参数,每次左移一位,$#减1。
# 循环处理传入的所有文件
while [ $# -gt 0 ]; do
echo "处理文件:$1"
shift
done
加数字比如shift 2,就是左移两位。
点命令(.)和source一样,在当前shell执行脚本,不是子进程,所以脚本里的变量当前shell能用。
# 执行config.sh,里面的变量当前shell可用
. ./config.sh
# 或者用source
source ./config.sh
wait等待所有后台任务结束,返回值总是0;也可以加PID等特定进程。
# 启动两个后台任务
sleep 10 &
sleep 5 &
echo "等待后台任务完成..."
wait
echo "所有后台任务都完成了"