概述
可以说,以下大部分知识点都是本人经过无数次踩雷o(╥﹏╥)o 之后进行的一些些总结了。
测试脚本相关信息
[root@myhost yuki]# pwd
/yuki
[root@myhost yuki]# ll
total 4
-rwxr-xr-x 1 root root 36 Dec 6 09:35 test.sh
在脚本中获取当前执行的脚本名称
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $0
[root@myhost yuki]# sh /yuki/test.sh
/yuki/test.sh
[root@myhost yuki]# ./test.sh
./test.sh
如何在命令行向脚本传参?
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $1
echo $2
[root@myhost yuki]# sh /yuki/test.sh ac bd
ac
bd
如何计算传递进来的参数的个数?
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $#
[root@myhost yuki]# sh /yuki/test.sh ac bd
2
######################################################################
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $#
[root@myhost yuki]# sh /yuki/test.sh {a..z}
26
获取传递进来所有参数的值(把传进来的所有参数当成一个整体,即当成一个字符串)
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $*
[root@myhost yuki]# sh /yuki/test.sh {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
#不推荐使用
获取传递进来所有参数的值(传进来的所有参数还是单独的个体)
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $@
[root@myhost yuki]# sh /yuki/test.sh {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
#推荐使用,这是将参数传递给其他程序的最佳方式, 以 $IFS 为分隔符列出所有传递到脚本中的参数。
如何列出第二个字母是 a 或 b 的文件 ?
[root@myhost ~]# ll
total 8
drwxr-xr-x 2 root root 4096 Jul 10 15:03 pic
drwxr-xr-x 3 root root 4096 Aug 17 2017 project
[root@myhost ~]# ls -d ?[ir]*
pic project
如何输出当前 shell 的 PID ?
[root@myhost ~]# echo $$
27460
bash 中 $! 表示什麽意思 ?
后台最近执行命令的 PID。
每个脚本开始的 #!/bin/sh 或 #!/bin/bash 表示什麽意思 ?
这一行说明执行此脚本时要使用的哪一种shell解释器。
#!/bin/bash 表示脚本使用 /bin/bash。
对于 python 脚本,就是 #!/usr/bin/python。
如何查看上一行命令/上个一脚本是否执行成功?
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $#
echo $?
[root@myhost yuki]# sh /yuki/test.sh ac bd
2
0
查看文本最后n行
tail -n /yuki/test.sh
查看文本最前n行
head -n /yuki/test.sh
获取文件每一行的第n个元素的值
awk '{print $n}' /yuki/test.sh
cat /yuki/test.sh | awk '{print $n}'
假设文件中的每一行的第一个元素的值是"shell",如何获取这一行的第n个元素的值?
awk '{ if ($1 == "shell") print $n}' /yuki/test.sh
cat /yuki/test.sh | awk '{ if ($1 == "shell") print $n}'
如何使用 awk 列出 UID 小于 100 的用户 ?
[root@myhost ~]# tail -3 /etc/passwd
saslauth:x:995:76:Saslauthd user:/run/saslauthd:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
[root@myhost ~]# awk -F ":" '$3<100' /etc/passwd
[root@myhost ~]# awk -F ":" '{if($3<100) print $0}' /etc/passwd
[root@myhost ~]# cat /etc/passwd|awk -F ":" '{if($3<100) print $0}'
命令:[ -z “” ] && echo 0 || echo 1 的输出是什麽?
0
#字符串长度如果是zero,就执行&&后面的语句
#字符串长度如果不是zero,就执行||后面的语句
如何去除字符串中的所有空格 ?
echo ${string} | tr -d " "
注意:输出打印时用单引号、双引号以及不用引号的区别。
[root@myhost ~]# name=John && echo 'My name is $name'
My name is $name
[root@myhost ~]# name=John && echo "My name is $name"
My name is John
[root@myhost ~]# name=John && echo My name is $name
My name is John
#笔记:
# 单引号 - 当我们不希望把变量转换为值的时候使用它。
# 双引号 - 计算所有变量的值并用值代替。
变量判断/替换
[root@myhost ~]# echo ${new:-variable}
variable
[root@myhost ~]# new=3
[root@myhost ~]# echo ${new:-variable}
3
#当${new}变量还未被赋值的时候(值为空时,输出后边变量的值)
#当${new}变量被赋值的时候(值不为空时,输出${new}变量的值)
按照if语句来理解:
if [ -z ${new} ];
then
echo ${variable}
else
echo ${new}
fi
如何打印变量的最后 5 个字符 ?
echo ${variable: -5}
#冒号后面有空格
${variable:-10} 和 ${variable: -10} 有什麽区别?
${variable:-10}
#冒号后面没有空格,表示: - 如果之前没有给 variable 赋值则输出10;如果有赋值则输出该变量variable的值;
${variable: -10}
#冒号后面有空格,表示:直接输出 variable变量 的最后10个字符。
如何只用 echo 命令替换字符串的一部分 ?
echo ${variable//pattern/replacement}
哪个命令将命令替换为大写 ?
tr '[:lower:]' '[:upper:]'
如何只用 echo 命令获取字符串变量${variable}的指定的一部分 ?
[root@myhost ~]# variable="My name is Petras, and I am developer."
[root@myhost ~]# echo ${variable:11:6}
Petras
#笔记:
#echo ${variable:x:y}
#x - 起始位置(下标从0开始)
#y - 长度
如果给定字符串 variable=“User:123:321:/home/dir”,如何只用 echo 命令获取 home_dir ?
[root@myhost ~]# variable="User:123:321:/home/dir"
[root@myhost ~]# echo ${variable#*:*:*:}
/home/dir
[root@myhost ~]# echo ${variable##*:}
/home/dir
如何从定字符串 variable=“User:123:321:/home/dir” 字符串中获取 “User” ?
[root@myhost ~]# variable="User:123:321:/home/dir"
[root@myhost ~]# echo ${variable%:*:*:*}
User
[root@myhost ~]# echo ${variable%%:*}
User
如何在 bash shell 中更改标准的域分隔符为 “:” ?
IFS=":"
如何获取字符串变量和数组变量的长度 ?
${#string}
${#array@}或${#array*}
如何获取字符串变量和数组变量的值?
${string}
${array@} 或${array[i]}
命令 “export” 有什麽用 ?
将变量的值引入到子shell中,从而使变量在子 shell 中可用。
“export $variable” 或 “export variable” 哪个正确 ?
export variable
如何在后台运行脚本 ?
nohup command&
大部分时间我们可能是远程使用Linux,我碰到过由于网络断线使得在后台运行的command &没了...
“chmod 500 script” 做什麽?
使脚本所有者拥有可读和可执行权限。
“>” 和 “>>” 是干什麽用的 ?
都是重定向输出流到文件或另一个流。
">" 再次重定向时会覆盖之前的内容;
">>" 再次重定向时不会覆盖之前的内容,是将新的内容追加到之前内容的后面。
如何在脚本文件中重定向标准输出和标准错误流到 log.txt 文件 ?
在脚本文件中添加 "exec >log.txt 2>&1" 命令。
& 和 && 有什麽区别?
& - 希望脚本在后台运行的时候使用它
&& - 当前一个脚本成功完成才执行后面的命令/脚本的时候使用它
如何对自己的shell脚本进行调试?
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo $#
echo $?
######################################################################
[root@myhost yuki]# sh /yuki/test.sh a1 b2
2
0
######################################################################
[root@myhost yuki]# sh -x /yuki/test.sh a1 b2
+ echo 2
2
+ echo 0
0
######################################################################
[root@myhost yuki]# sh -v /yuki/test.sh a1 b2
#!/bin/sh
echo $#
2
echo $?
0
######################################################################
[root@myhost yuki]# sh -xv /yuki/test.sh a1 b2
#!/bin/sh
echo $#
+ echo 2
2
echo $?
+ echo 0
0
shell脚本中如何声明变量,这里强调格式(赋值等号前后是否有空格)
#格式1:赋值等号后有空格
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1= "hello"
echo ${v1}
[root@myhost yuki]# sh /yuki/test.sh
/yuki/test.sh: line 3: hello: command not found
#格式2:赋值等号前有空格
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1 ="hello"
echo ${v1}
[root@myhost yuki]# sh /yuki/test.sh
/yuki/test.sh: line 3: v1: command not found
#格式3:赋值等号前后都有空格
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1 = "hello"
echo ${v1}
[root@myhost yuki]# sh /yuki/test.sh
/yuki/test.sh: line 3: v1: command not found
#格式4:赋值等号前后都没有空格
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1="hello"
echo ${v1}
[root@myhost yuki]# sh /yuki/test.sh
hello
###结论:shell中给变量赋值时赋值等号前后都不能有空格!!!
如何连接两个字符串?
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1="hello"
v2=",world"
echo ${v1}${v2}
[root@myhost yuki]# sh /yuki/test.sh
hello,world
如何进行两个数的数学运算?
方法1:两个小括号
用于整数运算,效率很高,推荐使用。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1=3
v2=9
echo $(($v1+$v2))
v3=$(($v1+$v2))
echo $v3
[root@myhost yuki]# sh /yuki/test.sh
12
12
方法2:let命令
用于整数运算,和 (()) 类似。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1=3
v2=9
let v3=v1+v2
echo $v3
[root@myhost yuki]# sh /yuki/test.sh
12
方法3:一个中括号
用于整数运算,不如 (()) 灵活。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1=3
v2=9
v3=$v1+$v2
echo $[v3]
echo $[$v1+$v2]
[root@myhost yuki]# sh /yuki/test.sh
12
12
方法4:expr命令
用于整数运算,也可以处理字符串。比较麻烦,需要注意各种细节,不推荐使用。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
echo "#用expr命令可以直接运算并打印出结果,而不再需要echo命令进行打印"
echo "####错误的格式(因为expr表达式中的运算符前后都需要空格)"
v1=3
v2=9
expr $v1+$v2
echo "####修改之后能够计算出正确的结果"
v1=3
v2=9
expr $v1 + $v2
v3=`expr $v1 + $v2`
echo $v3
[root@myhost yuki]# sh /yuki/test.sh
#用expr命令可以直接运算并打印出结果,而不再需要echo命令进行打印
####错误的格式(因为expr表达式中的运算符前后都需要空格)
3+9
####修改之后能够计算出正确的结果
12
12
方法5:管道+bc命令
bc命令是linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1=3
v2=9
echo $v1+$v2 | bc
v3=$v1+$v2
echo $v3 | bc
[root@myhost yuki]# sh /yuki/test.sh
12
12
方法6:awk命令
格式比较复杂,不推荐使用。
[root@myhost yuki]# cat /yuki/test.sh
#!/bin/sh
v1=3
v2=9
awk 'BEGIN{print '"$v1"'+'"$v2"'}'
awk 'BEGIN{print '$v1'+'$v2'}'
#注意:运算符前后、中括号前后都没有空格
[root@myhost yuki]# sh /yuki/test.sh
12
12
如何将整数 a 加到 b 并赋值给 c ?
c=$((a+b))
或
c=`expr $a + $b`
或
c=`echo "$a+$b"|bc`
如何计算本地用户数目 ?
[root@myhost ~]# wc -l /etc/passwd
36 /etc/passwd
[root@myhost ~]# wc -l /etc/passwd|cut -d" " -f1
36
或者
[root@myhost ~]# cat /etc/passwd|wc -l
36
计算用户主组数目并显示次数和组名
[root@myhost ~]# cat /etc/passwd|cut -d: -f4|sort|uniq -c|while read c g
> do
> { echo $c; grep :$g: /etc/group|cut -d: -f1;}|xargs -n 2
> done
###回车之后出现以下结果:
5 root
1 bin
1 users
1 mail
1 avahi-autoipd
1 daemon
1 nscd
1 ntp
1 adm
1 mailnull
1 ftp
1 smmsp
1 tss
1 lp
1 tcpdump
1 sshd
1 saslauth
1 dbus
1 postfix
1 nobody
1 memcached
1 polkitd
1 systemd-network
1 systemd-bus-proxy
写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ?
for i in {0..100..3};
do
echo $i;
done
或者
for (( i=0; i<=100; i=i+3 ));
do
echo "Welcome $i times";
done
shell 中如何进行数字比较?
在[]中使用比较符 | 在[[]] 和(())中使用比较符 | 说明 |
---|---|---|
-eq | == | equal的缩写,表相等 |
-nq | != | not equal 的缩写,表不相等 |
-gt | == | 大于,greater than |
-ge | == | 大于等于,greater equal |
-lt | == | 小于,less than |
-le | == | 小于等于,less equal |
提示:
“<” 符号的意思是小于, if [[ “
a
"
<
"
a" < "
a"<"b” ]],if [ “KaTeX parse error: Expected 'EOF', got '\<' at position 4: a" \̲<̲ "b” ], 在单[]中需要转义,因为shell 也用 “<” 和">" 表示重定向;
“>” 符号的意思是大于, if [[ “
a
"
>
"
a" > "
a">"b” ]],if [ “KaTeX parse error: Expected 'EOF', got '\>' at position 4: a" \̲>̲ "b” ], 在单[]中需要转义,因为shell 也用 “<” 和">" 表示重定向;
关系运算符只支持数字(整数),不支持字符串,除非字符串的值是数字(整数)。
条件表达式要放在方括号之间,并且要有空格,例如: if [[“
a
"
=
=
"
a" =="
a"=="b”]]是错误的,必须写成 if [[ “
a
"
=
=
"
a" =="
a"=="b” ]]
shell 中如何进行字符串比较?
shell中的逻辑运算符如何使用?
shell中的文件测试运算符如何使用?
怎样过滤出文件中注释行和空白行?
egrep -v "#|^$" 文件名
shell 脚本如何获取输入的值 ?
a) 通过参数
./script param1 param2
b) 通过 read 命令
read -p "Destination backup Server : " desthost