1. 脚本的sha-bang,告诉系统指定一个解释器,可以是shell,程序语言或者任意一个通用程序,这个指定的程序从头开始解释执行脚本中的命令。
1 #!/bin/sh
2 #!/bin/bash
3 #!/usr/bin/perl
4 #!/usr/bin/tcl
5 #!/bin/sed -f
6 #!/usr/awk -f
例:
cat /usr/share/doc/openssl/REDME>/data/b.sh
在b.sh最上面添加 #!/bin/more
chmod +x b.sh
./b.sh #执行该脚本,会自动调用more进行展示
2. 调用脚本
使用 sh scriptname 来调用脚本的时候将会关闭一些 Bash 特定的扩展,脚本可能因此而调用失败
3. 调用变量加引号和不加引号的一些小区别
[root@centos8-3-node1 data]#num=`seq 5`
[root@centos8-3-node1 data]#echo $num
1 2 3 4 5
[root@centos8-3-node1 data]#echo "$num"
1
2
3
4
5
[root@maple bin]# [ -n $xyz ]
[root@maple bin]# echo $?
0
[root@maple bin]# [ -n "$xyz" ]
[root@maple bin]# echo $?
1
[root@maple bin]# [ $xyz ]
[root@maple bin]# echo $?
1
xyz是未定义变量,默认状态为NULL,与0不同。
因此建议使用"" 是一个好习惯。
4. [ 的 -a和-e的取反区别
-a判断文件是否存在和-e功能一样。
但是当取反操作时,-a无效,-e可以。
在高级bash脚本编程指南一本书中,建议使用-e。
[root@centos8 data]# [ -a /etc/passwd ]
[root@centos8 data]# echo $?
0
[root@centos8 data]# [ ! -a /etc/passwd ]
[root@centos8 data]# echo $?
0
[root@centos8 data]# [ ! -e /etc/passwd ]
[root@centos8 data]# echo $?
1
6. 调用变量比较时 最好加上双引号 [ = wang ]
如果在进行变量比较时,
N
A
M
E
写
成
了
NAME写成了
NAME写成了NAMM,那么在进行比较时,会形成 [ = Liang ] 这种比较,会报错。
应该在调用$NAME时加上双引号。即使输错 也会形成 [ “” = Liang ]进行比较,不会报错。
#!/bin/bash
NAME="Liang"
[ $NAMM = Liang ] && echo "你好,$NAME"||echo "Who are you?"
[root@centos8 data]# ./hello.sh
./hello.sh: line 5: [: =: unary operator expected
Who are you?
#!/bin/bash
NAME="Liang"
[ "$NAMM" = Liang ] && echo "你好,$NAME"||echo "Who are you?"
[root@centos8 data]# ./hello.sh
Who are you?
7.shell中 ∗ 和 *和 ∗和@的区别
在下面例子中可以看到,$*是将整个所有参数当作一个字符串传给file.sh,
@
则
是
将
字
符
串
分
隔
,
一
个
一
个
传
给
f
i
l
e
.
s
h
。
下
列
情
况
只
在
@则是将字符串分隔,一个一个传给file.sh。 下列情况只在
@则是将字符串分隔,一个一个传给file.sh。下列情况只在*和$@被双引号括起来时才会生效。
只写
∗
和
*和
∗和@这两个没有区别,都是将字符串分隔,一个一个传给file.sh
"$@" 要比 "$*" 用得多。由于 "$*" 将所有的参数当作单个字符串,因此它很少被使用。
[root@centos8 testshells]# cat f1.sh
#!/bin/bash
echo first args is $1
echo second args is $2
echo 'use $*'
./file.sh "$*"
[root@centos8 testshells]# cat f2.sh
#!/bin/bash
echo first args is $1
echo second args is $2
echo 'use $@'
./file.sh "$@"
[root@centos8 testshells]# cat file.sh
#!/bin/bash
echo "file.sh:1st is $1"
[root@centos8 testshells]# ./f1.sh a b c
first args is a
second args is b
use $*
file.sh:1st is a b c
[root@centos8 testshells]# ./f2.sh a b c
first args is a
second args is b
use $@
file.sh:1st is a
8.read通过管道读取值,为什么打印变量不显示
问题:
[root@centos8 testshells]# echo 1 2 |read x y ;echo x=$x,y=$y
x=,y=
原因:Each command in a pipeline is executed as a separate process
在管道符中每一个命令都是独立的进程。
验证:
[maple@centos8 ~]$ echo $BASHPID
2374
[maple@centos8 ~]$ echo $BASHPID >a.txt | echo $BASHPID > b.txt;echo $BASHPID >c.txt; echo $BASHPID >d.txt
[maple@centos8 ~]$ cat {a..d}.txt
2784
2785
2374
2374
结论:管道前后的命令都是在独立的进程中执行的," ;"之后的命令是在当前bash执行的。 说明之前的问题是在当前bash进程获取不到子进程的变量。
解决:
[maple@centos8 ~]$ echo $BASHPID
2374
[maple@centos8 ~]$ echo $BASHPID >a.txt | { echo $BASHPID > b.txt;echo $BASHPID >c.txt; }; echo $BASHPID >d.txt
[maple@centos8 ~]$ cat {a..d}.txt
2813
2814
2814
2374
[root@centos8 testshells]# echo 1 2 | { read x y ;echo x=$x,y=$y; }
x=1,y=2
9. SHELL中case判断非数字的写法
case $1 in
*[!0-9]*)
echo "Not no";
;;
*)
echo num
;;
esac
上面第一种情况必须出现输入的字符带有不包含数字的字符。
那么纯数字的情况下不符合第一种情况。这样就匹配出来了纯数字的情况。
未完待更新····