shell学习三-----特殊变量

时间:2023-01-17 15:39:09
位置变量
1、$0 获取当前执行的shell脚本的文件名,包含脚本的路径(如果带路径)。
[root@node01 day2]# sh n.sh 
n.sh
[root@node01 day2]# sh `pwd`/n.sh
/data/day2/n.sh


[root@node01 day2]# vi n.sh 
dirname $0
basename $0            
[root@node01 day2]# sh `pwd`/n.sh
/data/day2
n.sh


[root@node01 day2]# vi /etc/init.d/crond 
。。。。。
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-
reload}"
[root@node01 day2]# /etc/init.d/crond 
Usage: /etc/init.d/crond {start|stop|status|restart|condrestart|try-restart|reload|force-reload}


dirname  取目录
basename 取名字
[root@node01 day2]# dirname `pwd`/n.sh
/data/day2
[root@node01 day2]# basename `pwd`/n.sh
n.sh
====================================================================================
2、单小括号 ()
把命令作为变量定义的方法
①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。
括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。


②命令替换。等同于`cmd`,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得
到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。


③用于初始化数组。如:array=(a b c d)


$()     ----------很常用,如date uname which等
例子1:
[root@node01 ~]# CMD=$(date +%F)
[root@node01 ~]# echo $CMD
2017-07-29
[root@node01 ~]# echo $CMD.tar.gz
2017-07-29.tar.gz
[root@node01 ~]# echo `date +%F`.tar.gz
2017-07-29.tar.gz
[root@node01 ~]# tar -zcvf tmp_$(date +%F).tar.gz /tmp
[root@node01 ~]# tar -zcvf etc_$(date +%F).tar.gz /etc
[root@node01 ~]# ls -lrt
total 86384
-rw-r--r--  1 root root  8491533 Nov 18  2015 apache-maven-3.3.9-bin.tar.gz
-rw-r--r--  1 root root 69875039 Mar  2 03:14 jenkins.war
-rw-r--r--. 1 root root    10033 Jul  7 07:49 install.log.syslog
-rw-r--r--. 1 root root    49957 Jul  7 07:52 install.log
-rw-------. 1 root root     1598 Jul  7 07:52 anaconda-ks.cfg
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Templates
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Public
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Pictures
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Music
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Downloads
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Documents
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Desktop
drwxr-xr-x. 2 root root     4096 Jul  8 06:54 Videos
-rw-r--r--  1 root root     4299 Jul 28 23:59 whoami-strace.txt
-rw-r--r--  1 root root       12 Jul 29 07:17 grep.log
-rw-r--r--  1 root root      733 Jul 29 07:41 tmp_2017-07-29.tar.gz
-rw-r--r--  1 root root  9957466 Jul 29 07:43 etc_2017-07-29.tar.gz


例子2:
for i in $(seq 0 4);do echo $i;done  
for i in `seq 0 4`;do echo $i;done  
for ((i=0;i<5;i++));do echo $i;done  
for i in {0..4};do echo $i;done  
=========================================================================
3、$n 获取当前执行脚本的第n个参数值,n=1..9,当n为0表示脚本的文件名,如果n大于9,大括号括起来${}.
n是取值范围可以取值1、2 、3 、4。。。。。一旦大于9就需要大括号扩起来${}
 /etc/init.d/cront start  ddd ggg ddd "ddd fff"    取脚本的传参  
                    $1    $2   $3  $4   $5
例子1:[root@node01 day2]# vi p.sh
echo $1
[root@node01 day2]# sh p.sh wolf
wolf
[root@node01 day2]# sh p.sh wolf yu   yu没结果,没有接收的
wolf
[root@node01 day2]# sh p.sh "wolf yu"
wolf yu
例子2:
[root@node01 day2]# seq 15|sed 's#^#$#g' 
$1
$2
$3
$4
$5
$6
$7
$8
$9
$10
$11
$12
$13
$14
$15
[root@node01 day2]# seq 15|sed 's#^#$#g' |tr "\n" " "   
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@node01 day2]# 
[root@node01 day2]# seq -s " " 15|sed 's# # $#g'
1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@node01 day2]# seq -s " " 15|sed 's# # $#g' >q,sh
[root@node01 day2]# cat q,sh `
> ^C
[root@node01 day2]# cat q,sh 
1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@node01 day2]# vi q.sh
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
大于9需要大括号括起来
[root@node01 day2]# sh q.sh {a..z} 
a b c d e f g h i a0 a1 a2 a3 a4 a5


(后面的都不对了)
[root@node01 day2]# vi q.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@node01 day2]# sh q.sh {a..z}
a b c d e f g h i j k l m n o
===================================================================
4、$#获取当前执行的脚本shell脚本后面接的参数的总个数
例子1:
[root@node01 day2]# vi q.sh       
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
echo $#


[root@node01 day2]# sh q.sh {a..z}   跟接收没关系,统计传参个数
a b c d e f g h i j k l m n o
26
作用:判断参数的个数
例子2:工作中可以控制用户的输入
[root@node01 day2]# vi q1.sh
[ $# -ne 2 ] && {
echo "muse two"
exit 1
}
[root@node01 day2]# sh q1.sh ccc
muse two
[root@node01 day2]# vi q1.sh    
[ $# -ne 2 ] && {
echo "muse two"
exit 1
}
echo wolf
[root@node01 day2]# sh q1.sh ccc
muse two
[root@node01 day2]# sh q1.sh ccc ddd
wolf
=====================================================================
5、$? 获取执行上一个指令的返回值(0为成功,非0为失败)#这个变量很常用
例子1:
[root@node01 day2]# su - wolf
welcome to wolf linux
[wolf@node01 ~]$ ll
total 0
[wolf@node01 ~]$ echo $?
0
[wolf@node01 ~]$ ll /root
ls: cannot open directory /root: Permission denied
[wolf@node01 ~]$ echo $? 
2
[wolf@node01 ~]$ ddd
-bash: ddd: command not found
[wolf@node01 ~]$ echo $?
127
[wolf@node01 ~]$ sleep 10
^C
[wolf@node01 ~]$ echo $?
130
例子2:
make && echo?


$?参考
   0        成功
   2        权限拒绝
   1-125    表示失败:脚本命令、系统命令错误或者参数传递错误
   126      在该该命令了,但是无法执行
   127      找不到命令
   >128     系统被强制结束
====================================================================== 
6、在脚本调用,一般用exit 0 (我这里写的是exit 1),函数用retrun 0,这是写脚
本的人给自己看的脚本执行状态。当然如果不给,就按照系统给的来。
控制命令及脚本返回值。
例子1:
[root@node01 day2]# vi q1.sh 
[ $# -ne 2 ] && {
echo "muse two"
exit 111                       赋值给当前shell的$?变量了
}
echo wolf
[root@node01 day2]# sh q1.sh 
muse two
[root@node01 day2]# echo $?  
111
[root@node01 day2]#