基本shell知识

1、给变量赋值的时候,变量、等号、值之间不能有空格
2、如何将一个命令的输出赋值给一个变量?
使用`符号,比如将date命令的输出赋值给a这个变量
a=`date`或者a=$(date)
这个用法很有意义,比如说可以用在日志文件的生成上面:

#!/bin/sh
file=`date +%Y%m%d`
ls > ${file}.log

3、export一个变量,对子进程的影响
如果一个变量没有export,那么这个变量是不会加入到当前shell的环境变量的,因此子进程也不会看到这个变量的值。
4、子进程与子shell的区别
先看一段代码:

unset abcd
abcd=1
(echo "a=${a}")
sh -c 'echo a=${a}'

这段代码的输出:

a=1
a=

首先说明一下,把命令括起来是什么意思:使用子shell执行这条命令。
sh -c 'echo a=${a}'这条命令是生成一个子进程来执行这条命令

子shell输出了a=1,因为子shell其实是父进程fork出了一个子进程,这个子进程和父进程几乎是一样的(除了一些没办法赋值的量),当然a也被复制了一份,所以子shell输出a=1;但是sh -c 'echo a=${a}'这条命令也是父进程fork出一个子进程执行这条命令,但是在fork之后,执行了exec函数,重新执行了bash程序,因此代码段、变量什么的都被新的程序替换了,因此a的值也就是空,但是注意到在执行exec函数的时候,会传进去环境变量。这也是为什么export之后的变量可以在子进程中看到的原因。

5、在使用管道时,Linux系统实际上会同时运行管道符号前后的两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区。

测试程序:
test.sh

#!/bin/bash
echo "abcd"
sleep 3
echo "efg"

在shell里面运行./test.sh | cat
可以看到第一个命令还没执行完就有了输出。

6、if语句
(1)格式:

if command
then
	command
fi

记住if判断的是command是否退出状态为0,而不是command执行完是true还是false。
(2)if-then-else语句
格式:

if command
then
	command
else
	command
fi

(3)if-then-elif
格式:

if command
then
	command
elif command
then
	command
fi

我们一般在程序中是要判断条件是否成立,但是这里只能判断命令的退出状态,有什么命令可以满足这种需求呢,有!,这个命令就是test,这个命令如果不成立,则返回状态不为1,成立则返回状态0.

7、if判断的几种类型
(1)数值比较

n1 -eq n2       n1是否等于n2
n1 -ne n2       n1是否不等于n2
n1 -ge n2       n1是否大于或等于n2
n1 -gt n2       n1是否大于n2
n1 -le n2       n1是否小于等于n2
n1 -lt n2       n1是否小于n2

(2)字符串比较

str1 = str2           str1是否等于str2,=两边要有空格,否则为赋值了
str1 != str2          str1是否不等于str2
str1 < str2           str1是否小于str2
str1 > str2           str1是否大于str2
-n str1               str1长度是否非0
-z str1               str1长度是否为0,即为NULL

(3)文件比较

-d file 检查file是否存在并是一个目录
-e file 检查file是否存在
-f file 检查file是否存在并是一个文件
-r file 检查file是否存在并可读
-s file 检查file是否存在并非空
-w file 检查file是否存在并可写
-x file 检查file是否存在并可执行
-O file 检查file是否存在并属当前用户所有
-G file 检查file是否存在并且默认组与当前用户相同
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧

(4)逻辑判断

-a         与 
-o        或 
!        非

8、复合条件测试

[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]

9、for循环
格式:

for var in list
do
	commands
done

比如,打印当前目录下面所有的文件名(不包括隐藏文件)

#!/bin/bash
for test in *
do
        echo $test
done

值list的列表默认是使用空格分隔的,若值本身就包含空格,那么使用双引号把值包起来,双引号并不作为值的一部分。
10、while循环

while test command
do
	other commands
done

11、如何使用数值型变量
使用let命令
比如我们需要打印当前文件夹下面的前十个文件

#!/bin/bash
let i=0
for file in *
do
        if [ $i -ge 10 ]
        then 
                break
        else
                let i++
                echo $file
        fi
done

12、如何处理命令行参数
在需要对命令传参数时,我们可以使用一些特殊的变量

$#               命令行参数的个数
$0               命令的名称
$1               命令行的第一个参数
$2               命令行的第二个参数,依此类推
$?               上一次命令的退出状态
$*               全部命令行参数
$@               全部命令行参数,与$*稍有差别

在运行脚本时我们可能会对脚本传进一些参数,以此来决定控制脚本的运行行为:例如

./test.sh -a -b input.txt

假设这个命令行的意思是test.sh这个脚本使用了-a这个选项,也使用了-b这个选项,并且-b这个选项还带了一个参数input.txt,那么怎么在程序中识别这些参数呢。
最简单的就是在程序中使用case,对有效的选项进行判断,例如:

#!/bin/bash
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "option -a";;
                -b) para=$2
                        echo "option -b with para $para"
                        shift;;
                # 默认--后面的参数是作为命令行的参数,而不是选项的参数
                --) shift   
                        break;;
                *) echo "$1 is not a option";;
        esac
        shift
done

尝试运行一下test.sh

root@ubuntu:~/traninig/shell_test$ ./test.sh -a -b 1
option -a
option -b with para 1

这样当然是比较简单的命令选项,当遇到组合选项怎么办,例如:

./test.sh -ab 1

这时候就要使用getopt这个命令来解析选项,解析选项的格式是这样的

getopt 选项排列(如选项带参数,则选项后面加冒号)   命令选项

仍使用上面的例子,使得./test.sh -ab 1能够正确解析

root@ubuntu:~/traninig/shell_test$ getopt ab: -ab 1
 -a -b 1 --

说明:

getopt   解析组合选项的命令
ab:      说明需要使用的选项,都是单个字母一个选项
-ab 1    组合选项
输出:-a -b 1 --   这个就是简化了的命令行选项参数,可以使用上面的办法进行解析

把这个使用到程序中

#!/bin/bash
#set命令将--后面的内容设置成命令行参数,也就是$@
set -- $(getopt ab: "$@")
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "option -a";;
                -b) para=$2
                        echo "option -b with para $para"
                        shift;;
                --) shift
                        break;;
                *) echo "$1 is not a option";;
        esac
        shift
done

测试:

root@ubuntu-146:~/traninig/shell_test$ ./test.sh -ab 1
option -a
option -b with para 1

但是这个getopt不能处理参数里面有空格

root@ubuntu-146:~/traninig/shell_test$ ./test.sh -ab "1 2"
option -a
option -b with para 1
2 is not a option

为了能够在命令选项参数中使用空格,需要使用getopts命令进行选项参数的解析,getopts的使用和getopt的使用方法有较大的不同

#!/bin/bash
while getopts ab: opt
do
        case "$opt" in
                a) echo "option -a";;
                b) echo "option -b with para $OPTARG";;
                *) echo "unknown option $OPTARG";;
        esac
done

首先,getopts的使用就不同,getopts首先就在内部把$@的内容解析好,然后依次填入opt进行判断,而且解析出来的内容也不同于getopt,很明显getopts解析出来的选项没有-,所以case中,选项的前面都没有-,另外还有两个环境变量,OPTARG和OPTIND,如果选项携带参数,那么OPTARG的内容就是参数,OPTIND代表getopts处理参数的位置,每处理完一个参数,OPTIND就会加1.这个OPTIND参数可以使用在传给命令的参数上面:

#!/bin/bash
while getopts ab: opt
do
        case "$opt" in
                a) echo "option -a";;
                b) echo "option -b with para $OPTARG";;
                *) echo "unknown option $OPTARG";;
        esac
done
shift $[ $OPTIND-1 ]
count=1
for para in "$@"
do
        echo "#para${count} : ${para}"
        shift
        let count++
done

13、输入输出重定向
输入重定向:

exec 3<&0               #将3重定向到0,也就是保存了标准输入
exec 0< inputfile       #将标准输入重定向到inputfile这个文件
exec 0<&3               #将0重定向到3,恢复标准输入
exec 3>&-               #将3重定向到-,这是一个特殊的描述符,意思就是关闭3

相应的,输出重定向:

exec 3>&1               #将3重定向到1,也就是保存了标准输出
exec 1> inputfile       #将标准输出重定向到inputfile这个文件
exec 1>&3               #将1重定向到3,恢复标准输出
exec 3>&-               #将3重定向到-,这是一个特殊的描述符,意思就是关闭3

重定向标准输入输出所使用的符号不一样,输出是">",输入时"<",除此之外基本相同。
当然也可以把一个文件描述符重定向到输入输出,但是这样可能会出现一些问题
14、多命令执行";“和“&&”
当使用”;“时,不论前面的命令是否执行成功,后面的命令都会执行
使用”&&"时,只有前面的命令都执行成功,后面的命令才会执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值