标签 shell 下的文章

有时候需要 linux 目录下文件分别打包,再分别解包,就需要用到 shell 中的 for 语句进行循环了。 当目录中有空格的时候,也容易发生报错,容易把一个目录名分隔为两个目录名,这时候就需要设置 IFS 这个值了。

具体测试可用的打包脚本如下:

#!/bin/bash

IFS=$'\n'

function tar_dir() {
for file in `ls -a $1`
        do
                if [ "$file" != "." -a "$file" != ".." ]; then
                        echo $file
                        tar cvf ${file}.tar $1"/"$file
                        echo "$file" >> tar_done.txt
                fi
        done
}

tar_dir $1

参考

https://blog.csdn.net/qq_40806289/article/details/114919068
https://blog.csdn.net/qq_28686911/article/details/115410830
https://blog.csdn.net/mr_leehy/article/details/76383091
https://blog.csdn.net/zhan570556752/article/details/80399154
https://blog.csdn.net/iamlihongwei/article/details/59114828

1. shell 单行注释使用 “#” 就可以了,多行注释:

:<<EOF

EOF

这个 EOF 可以换成其他,都可以,只要上下能够对应就可以。

参考:https://blog.csdn.net/lansesl2008/article/details/20558369 https://blog.csdn.net/tenfyguo/article/details/5753548

2. 检查文件是否存在:

if [ -f trials ]; then 
      rm trials
fi

参考: https://www.jb51.net/article/186273.htm

3. 退出脚本

exit 1

参考: https://blog.csdn.net/qq_35769944/article/details/81943543

4. 变量养成使用 {} 包起来的习惯

参考: https://www.runoob.com/linux/linux-shell-variable.html

5. 需要 python 脚本的时候,直接使用即可。

python3 test.py

参考: https://blog.csdn.net/zwt0909/article/details/52368559

6. -eq 更多用于数值的比较,字符串比较使用 ==

参考: https://www.jb51.net/article/56559.htm

7. 与逻辑: && 或者 -a,或逻辑: || 或者 -o

参考: https://blog.csdn.net/iamlihongwei/article/details/59114828 https://www.cnblogs.com/aaronLinux/p/8340281.html

8. 判断命令行参数缺失

if [ -z $1 ];then
      echo "You should input one parameter"
fi

参考: https://blog.csdn.net/geoffreychan/article/details/77823505

9. ssh 远程执行命令

ssh需要直接用密码执行命令需要在本地安装 sshpass

sudo apt install sshpass
ip="192.168.1.2"
user="xyz"
pswd="123456"

sshpass -p ${pswd} ssh ${user}@${ip} "cd /home ; ls"

在远程执行的命令需要用双引号包含起来,不同命令需要用分号隔开。

或者类似下面也可以

#!/bin/bash
ssh user@remoteNode > /dev/null 2>&1 << remotessh
cd /home
touch abcdefg.txt
exit
remotessh
echo done!

<< remotessh 和 remotessh 之间的内容在远程执行,别忘了用 exit 退出 ssh。重定向在于不显示远程输出。

参考: https://blog.csdn.net/jinking01/article/details/84386769 https://www.cnblogs.com/kaishirenshi/p/7921308.html

10. 自动输入密码 需要先安装 expect,然后使用 expect 命令

expect <<EXPECT_EOF
spawn sudo smbpasswd -a xyz
expect "New SMB password:"
send "123456\r"
expect "Retype new SMB password:"
send "123456\r"
expect eof
EXPECT_EOF

或者:

expect -c "
       spawn sudo smbpasswd -a xyz
       expect {
              \"New SMB password:\" {set timeout 300; send \"123456\r\";}
          \"Retype new SMB password:\" {send \"123456\r\"}
    }
#expect eof"

expect eof 是和 spawn 配对使用的。 在 bash 中直接用 expect,有两种用法,1. expect <<EXPECT_EOF EXPECT_EOF 这样配对使用; 2. expect -c " " 这样双引号之间使用。 {send "yes\r"; exp_continue;} 这样的用法,exp_continue 表示这个 expect 的 内容和 send 内容可以重复多次使用。

参考: https://www.cnblogs.com/old-path-white-cloud/p/11678517.html https://www.cnblogs.com/sharktech/p/7454767.html https://blog.csdn.net/zhongbeida_xue/article/details/78679549

https://blog.csdn.net/weixin_34354173/article/details/91895917 https://blog.csdn.net/zhangjikuan/article/details/51105166 https://www.cnblogs.com/lixigang/articles/4849527.html https://www.cnblogs.com/autopenguin/p/5918717.html

https://www.cnblogs.com/taosim/articles/3785817.html https://www.linuxidc.com/Linux/2017-02/140365.htm https://developer.aliyun.com/article/512290 https://blog.csdn.net/dongqing27/article/details/83108877

11. yes 命令可以一直输入 yes,直到被 kill 掉。

mkdir test
touch test/test.txt

yes | rm -rf ./test

kill -9 $(pidof yes)

类似于上面这种写法。 参考: https://blog.csdn.net/yasi_xi/article/details/8562002 https://www.linuxcool.com/yes https://man.linuxde.net/yes https://www.cnblogs.com/jins-note/p/9636969.html

12. patch 需要先安装 patch 包。

首先先把文件复制出来,修改,然后用 diff 生成 patch 文件

cp /etc/samba/smb.conf ./
vim smb.conf
diff -c /etc/samba/smb.conf smb.conf > smb_conf.patch

diff -c 选项是详细信息。

patch /etc/samba/smb.conf smb_conf.patch

参考: https://www.cnblogs.com/cute/archive/2011/04/29/2033011.html

13. 使用 scp 发送数据到远程

sshpass -p ${pswd} scp ~/bin/smb_conf.patch ${user}@${ip}:/home/${user}

参考: https://www.runoob.com/linux/linux-comm-scp.html

14. sudo 自动输入密码

echo "admin" | sudo -S service tomcat7 stop

参考: https://blog.csdn.net/wangbole/article/details/17579463

15. 代码块的结束符 EOF 之类的一定要顶格写,不要有空格,否则会报错,类似下面这样:

chmod_file()
{
    echo "chmod file"
    # ssh remote and exec command
    sshpass -p ${pswd} ssh ${user}@${ip} <<EOF

    chmod 400 ./.ssh/id_rsa
    chmod 644 ./.ssh/id_rsa.pub

    exit
EOF
}

16. 简单的 yes no免输入交互

echo "y" | rm /mnt/speech/.ssh/id_rsa*

17. 数组

array_name=(value1 value2 ... valuen)
array_name=()
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

echo "第一个元素为: ${array_name[0]}"

echo "数组的元素为: ${array_name[*]}"
echo "数组的元素为: ${array_name[@]}"

echo "数组元素个数为: ${#array_name[*]}"
echo "数组元素个数为: ${#array_name[@]}"

参考: https://www.runoob.com/linux/linux-shell-array.html

18. shell for 循环遍历数组

a=("Fdf" "df" "fd")
for str in ${a[@]};do
echo $str
done

参考: https://blog.csdn.net/weiwjacsdn/article/details/80368666

19. 函数参数使用 $1, $2 这样的。

参考: https://www.runoob.com/linux/linux-shell-func.html

20. 字符串按照空格拆分为数组

STR="123 A1 A2"
ARR=($STR)
echo "${ARR[0]}:${ARR[1]}:${ARR[2]}

参考: https://blog.csdn.net/weixin_44687868/article/details/108379011

21. 数组作为参数传递,也必须使用 ${xyz[*]} 这样形式的。

参考: https://blog.csdn.net/mydriverc2/article/details/78931628

22. 数组作为参数通过命令行传递,两种方法,一种是直接多个参数,还有一种是使用 " 双引号把数组框起来。

参考: https://www.runoob.com/linux/linux-shell-passing-arguments.html

23. 判断是否以 某个字符开头,比如 [ 这样的数组。

if [[ $cases =~ ^\[.* ]]; then
    casesStr=`cat ${target_json} |jq .cases[]| sed 's/\"//g'`
    cases=($casesStr)
else
    cases=($cases)
fi
echo "cases: ==> $cases"

参考: https://www.cnblogs.com/LiuYanYGZ/p/12491673.html

24. 从 json 文件中读取使用 jq 命令,获取数值的时候,如果只是字符串,那么使用 jq .abc 这样,如果是数组,那么使用 jq .abc[]

cases=`cat ${target_json} |jq .cases| sed 's/\"//g'`
casesStr=`cat ${target_json} |jq .cases[]| sed 's/\"//g'`

参考: https://www.cnblogs.com/nul1/p/12228785.html#3%E8%BE%93%E5%87%BA%E6%95%B0%E7%BB%84%E7%9A%84%E5%80%BC

25. find 控制搜索深度 使用 -maxdepth 这个参数, 使用 -type d 表明搜索的是目录。

find  ./  -maxdepth 3 -type d 

参考: https://blog.csdn.net/lmmcu_2012/article/details/52703395

26. sed 可以用来替换字符, s/old/new/g 这样的方式即可。

casesStr=`cat ${target_json} |jq .cases[]| sed 's/\"//g'`

参考: https://www.runoob.com/linux/linux-comm-sed.html