shell脚本的编写及运行
1. which命令和/etc/shells文件
which命令的功能:
which命令用于查找并显示给定命令的绝对路径,
环境变量$ PATH中保存了查找命令时需要遍历的目录。
which指令会在环境变量$PATH设置的目录里查找符合条件的文件。
使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。
/etc/shells文件:
/etc/shells文件是一个有效登陆shell的列表,可以查看可以使用的shell解释器,在登陆shell时,会查询这个文件。
2. 输出hello shell的脚本
2.1 脚本的编写
vim 01.sh #编写一个脚本(文件名必须以.sh结尾)
脚本内容:
#!/bin/bash #指定shell程序的解释器
echo "hello shell!" #这是一条输出语句
2.2 脚本的运行
运行方式不只有单一的一种,以下四种方式都可以用来执行shell脚本,根据个人不同的习惯来使用。
sh 01.sh
. 01.sh
source 01.sh
/bin/sh 01.sh
3. 接收用户的输入数据
read命令来从标准输入中读取用户输入的数据
$(占位符)表示变量
#!/bin/bash
# 从终端读取用户输入的数据 并赋值给preson变量
# read命令来从标准输入中读取用户输入的数据
echo "What is your name ?"
read preson
echo "hello, $preson"
4. 运行shell脚本的方式详解
运行 Shell 脚本有两种方法:一种在新进程中运行,一种是在当前 Shell 进程中运行
4.1 在新进程中运行shell脚本
在新进程中运行shell脚本有多种方法:
1)将shell脚本作为程序运行
shell脚本也是一种解释执行的程序,可以在终端直接调用(需要使用chmod命令给shell脚本加上执行权限)
注意: 通过这种方式运行脚本,脚本文件第一行的 #!/bin/bash 一定要写对,好让系统查找到正确的解释器。
chmod +x 01.sh #增加执行权限
./01.sh
./表示当前目录,整条命令的意思是执行当前目录下的01.sh 脚本。如果不写 ./ ,Linux会到系统路径(由PATH环境变量指定)下查找01.sh,而系统路径下显然不存在这个脚本,所以会执行失败。
2)shell脚本作为参数传递为bash解释器
你也可以直接运行Bash 解释器,将脚本文件的名字作为参数传递给Bash。
注意:通过这种方式运行脚本,不需要在脚本文件的第一行指定解释器信息,就算指定了也不会起作用。
/bin/bash 01.sh # 切换到01.sh所在的目录 使用bash的绝对路径
更简洁的方法是运行bash命令
bash是一个外部命令,shell会在/bin目录下找到对应的应用程序,即/bin/bash
which bash
bash 01.sh
3)两种写法的本质
这两种写法在本质上是一样的:第一种写法给出了绝对路径,会直接运行Bash 解释器;第二种写法通过 bash 命令找到 Bash 解释器所在的目录,然后再运行,只不过多了一个查找的过程而已。
4)检测是否开启了新进程
这两种写法都是在新进程中运行shell脚本,现在来检测一下是否开启了新进程:
Linux中每个进程都有一个唯一的ID,称为PID,使用$$变量就可以获取当前进程的PID
写脚本文件:
vim check.sh
内容:
#!/bin/bash
echo $$
执行:
chmod +x check.sh
./check.sh #新进程的PID
echo $$ #当前进程PID
/bin/bash check.sh #新进程的PID
进程的PID不一样,当然就是两个进程了
4.2 在当前进程中运行shell脚本
1)soucre命令
soucre命令是 Shell 内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。你也可以理解为 soucre命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。
source命令的用法:
source filename
也可以简写为:
. filename
两种写法的效果相同。对于第二种写法,注意点号 . 和文件名中间有一个空格。
使用source命令不用给脚本增加执行权限
2)检测是否在当前 shell 进程中
如何判断是不是新进程,查看脚本文件运行后的进程的pid和当前terminal的pid就可以
在shell中,可以使用$$变量获取当前进程的pid
source check.sh
当前进程的pid:
echo $$
两个进程的PID一样,是在当前进程中运行shell脚本。
3)shell脚本运行的方式
使用source或“ . ” 可以将自身脚本中的 变量值或函数等的返回值传递到当前父shell脚本中使用
写脚本:
vim 03.sh
内容:
#!/bin/bash
userdir=`pwd`
执行:
sh 03.sh
echo $userdir
source 03.sh
echo $userdir
我们可以得到以下结论:
子 shell 脚本会直接继承父shell脚本的变量、函数等,反之则不可以(就像儿子随父亲姓,基因也会继承父亲)。
如果希望反过来继承(就好像让父亲随儿子姓,让父亲的基因也继承儿子的),就要用source 或 “ . ”,在父shell脚本中事先加载子 shell 脚本。