








创建于 2022年4月29日 22:12:45 · 约2,051字
cat /etc/shells 查看系统支持哪些shell $SHELL当前用的啥
[ ⚡️Danger ] 指定解析器
#!/bin/bash
每个脚本开头都使用"#!",#!实际上是一个2字节魔法数字,这是指定一个文件类型的特殊标记,在这种情况下,指的就是一个可执行的脚本。在#!之后,接一个路径名,这个路径名指定了一个解释脚本命令的程序,这个程序可以是shell,程序语言或者任意一个通用程序。
使用bash a.sh的时候就不用+x
source or . a.sh也可以执行,在当前shell中一条一条执行,其他的都是开启一个子shell进程执行,可能会获取不到环境变量,子 shell 中设置的 当前变量,父 shell 是不可见的
直接bash命令相当于直接进入了子shell操作
[ ⚡️Danger ]
赋值的时候等号两边一定要空格,否则会被当成一体的字符串!!! 尤其是循环判断 变量类型会自动判断,小心!
使用env和printenv命令获取所有系统定义的变量
printenv可以不加$符,printenv HOME=echo $HOME
set 可以看到定义的所有变量和函数,自定义的也能看到
在命令行里 定义变量,a = 2,echo $a 弱类型,定义字符串用双引号括起来,双引号会自动识别变量表示符单引号不会读取为变量表示符
但是定义的是局部变量,使用export variable = 2设为全局变量
[ ⚠️Warning ]
在子shell里面修改全局变量只会在子范围里面生效,上级不会生效,export也没用
export只在本次会话中生效
约定俗成系统变量大写,自定义变量小写
默认等号后面都是字符串,如果要做数值运算,应该使用a = $((1+5)) or a = $[5+1]
静态常量 readonly a = 5 unset variable,从环境中删除variable
bin和sbin目录下都是系统的定义的可执行,查看$PATH就可以,路径添加到 $ PATH 的格式为 PATH=$PATH:<PATH1>:<PATH2>
或者编辑变量文件在最后直接export
可以设置环境变量有4个 优先级从高到底
#TODO 环境变量和优先级 理解 bashrc profile 优先级及区别 | Verne in GitHub
Linux文件 profile、bashrc、bash_profile区别 - 知乎
理解 bashrc 和 profile - { wido.me }
basename 命令路径可以获取最后一个/分割的内容,如果跟着第二个参数suffix就会去掉后缀
dirname 返回的是该文件的路径,也是简单的字符串分割
shell默认是不会解析基本数学表达式的,需要使用expr 1 + 2命令,注意必须要有空格,乘号使用*
命令替换使用两个反引号,把结果赋给变量。
为了解决麻烦,使用$((表达式))或$[表达式],在for和if中可以((expression))但是不提倡
test 命令检查某条件是否成立,可进行数值、字符和文件的测试,使用echo $?查看返回码0代表正常运行就是一样(好怪)
可以简写成[ condition ] 方括号一定要有空格,条件非空为True 1,空为False 0
字符串就=,!=,数值判断不能用符号,[4 -ne 5]~4≠5
| -eq | 等于(equal)= | -ne | 不等于(not equal)≠ |
|---|---|---|---|
| -lt | 小于(less than)< | -le | 小于等于(less equal)<= |
| -gt | 大于(greater than)> | -ge | 大于等于(greater equal)>= |
判断文件是否有权限
-r 读 -w 写 -x 执行
判断文件类型
-e 文件存在(existence) -f 存在且是文件(file) -d 存在且是目录(directory)
&& 与 || 或 ! 非[ ] && echo OK || echo notOK 整成三元运算符
在一个[]里进行与或判断的话,形式如下[ condition1 -a/-o condition2 ] and -a ; or -o
一般多个条件是[ cond1 ] && [ cond2 ]
if 命令格式有点不一样
shell
if [ expression ];then
process
fi
# 完全体
if [ expression ]
then
process
elif [ con ]
then
process
else
process
fi;作用是在一行里把两个命令隔开
[ 📌Tip ] if 使用时候的小技巧
在判断字符串后面拼接一个字符,即使不输入也不会报错if [ "$1"x="condition"x ];then
shell
case $variable in
value1)
process
;;
value2)
process
;;
*)
default
;;
esac就是switch case,语法真的奇怪
注意变量自加的写法
shell
# 普通for
for ((init;condition;variables-change))
do
process
done
# 增强for
for i in "a","b","c"
do
echo $i
done
# 一个递加到指定数的for操作,注意变量的使用和数学表达式
for((i=1;i<=$1;i++))
do
sum=$[ $sum + $i ]
done
echo $sum一般要在外面提前定义变量
shell
a=1
while [ $a -le $1 ]
do # 注释里为新写法
sum=$[ $sum+$a ] # let sum+=a
a=$[ $a + 1 ] # let a=a+1
doneshell
read -t 10 -p "输入你的名字" nameread 命令,只能在脚本文件里面使用,命令行里会出现-p: no coprocess
系统命令要使用命令替换,$( expression ) 实际上就是获得值赋予
自定义函数
shell
function f() # function 括号都能省略
{
variable=$[ $1 + $2 ] # 注意参数的定义
Action;
return int; # 省略return返回值是上一个函数语句执行完的$?状态码范围必须0-255整数
# 如果要返回数据,要配合使用
echo $variable
}
f $a $b # 注意参数的传入
# 返回值技巧
outer=$(f $a $b) # 输出结果就会被赋到outer调用之前必先声明,严格顺序,因为他就是单纯逐行执行。
grep awk sed cut vim+/ 后面可以直接使用正则,但是什么情况下会使用还不知道,之后再补充吧
cut -d "spliter" -f column1,2-5 file 以spliter为分割符取1,2到5列,-默认不填就是截到开头结尾 awk是gawk的软链接,是GNU的gawk的实现
默认以空格分割awk -F "spliter" '/regex pattern/ {action}'awk -F ":" -v i=100 'BEGIN{print "user, shell"} {print $1+i","$7} END{print "dahaige,/bin/zuishuai"}' passwd
以 : 为分割符,定义变量i = 100 开始前先打印一行"user, shell",打印第一列+i 结束时打印"dahaige,/bin/zuishuai"
| 内置变量 | 含义 |
|---|---|
| FILENAME | 文件名 |
| NR | 行号 |
| NF | 切割后列号 |
awk -F " " '/^'"$VALU"'/ {print $2}' 正则中使用外部变量
mesg,who -T 查看是否开启接收其他用户消息,mesg n/y关闭/打开消息write user tty 发送和接收方都会进入多行编辑模式。
要求:
shell
#!/bin/bash
# 判断参数是否为1
if [ $# -ne 1 ]
#!/bin/bash
# 判断参数是否为1
if [ $# -ne 1 ]
then
echo "参数个数错误,目录应为1"
exit
fi
# 获取路径
if [ -d $1 ]
then
echo ""
else
echo "目录不存在"
fi
DATE=$( date +%y-%m-%d )
DIRNAME=$( basename $1 )
DIRPATH=$(cd $(dirname $1);pwd )
FILE=archive_$DIRNAME_$DATE
echo "开始归档"
tar -czf /home/jack/$FILE $DIRPATH/$DIRNAME
if [ $? -eq 0 ]
then
echo "压缩完成"
else
echo "压缩失败"
fi
exit使用Linux自带的mesg和write命令向其他用户发送消息
shell
#!/bin/bash
# 获取用户列表注意列表的使用 l=(1 2 "3")
userlist=($(who -T | awk -F " " '{print $1}') )
# 检查参数
if [ $# -eq 2 ] && [[ "${userlist[@]}" =~ $1 ]] && [ $2 != "" ];then # 判断元素是否在列表里以及判空
USER=$1
MSG=$2
TTY=$(who -T | awk -F " " '/^'"$1"'/ {print $3}')
else
echo "args number is unsuitable"
fi
# 检查用户是否在线
if [ $(who -T | awk -F " " '/^'"$1"'/ {print $2}' ) = "+" ];then # awk 正则表达式使用外部变量
echo $MSG |write $USER $TTY
else
echo "user is offline"
fi
exit此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。