您当前的位置:首页 > 计算机 > 编程开发 > Shell

如何运行Shell脚本(在新进程中运行、在当前进程中运行)

时间:03-25来源:作者:点击数:

一、Shell脚本简单实例

在文本编辑器中编写代码如下,并保存为“test.sh”。

#!/bin/bash

echo "What is your name?" #这是一条语句
read PERSON
echo "Hello, $PERSON"

(1)这个文件的扩展名为.sh(sh代表shell),但其实扩展名并不影响脚本执行,见名知意就好。

(2)“#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。Shell的种类有很多,见博文常见的shell(sh、bash等)介绍

(3)echo 命令用于向标准输出文件(Standard Output,stdout,一般就是指显示器)输出文本。在.sh文件中使用命令与在终端直接输入命令的效果是一样的。

(4)#及其后面的内容是注释。Shell 脚本中所有以#开头的都是注释(当然以#!开头的除外)。

(5)read 命令用来从标准输入文件(Standard Input,stdin,一般就是指键盘)读取用户输入的数据。这个数据传给PERSON变量。

(6)最后一行表示输出变量 PERSON 的内容。注意在变量名前边要加上$,否则变量名会作为字符串的一部分处理。

二、运行Shell脚本的方法

1、在新进程中运行Shell脚本

法1、将 Shell 脚本作为程序运行

(1)首先让脚本具有可执行权限,然后执行脚本。这是在新进程中运行Shell脚本。

xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ll test.sh
-rw-r--r-- 1 root root 93 Feb 24 13:44 test.sh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ chmod 777 test.sh
chmod: 更改"test.sh" 的权限: 不允许的操作
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ sudo chmod 777 test.sh
[sudo] password for xjh: 
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ll test.sh
-rwxrwxrwx 1 root root 93 Feb 24 13:44 test.sh*
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ test.sh
test.sh:未找到命令
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ./test.sh
What is your name?
xjh
Hello, xjh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$

(2)执行脚本时,要写成./test.sh,而不是test.sh。运行其它二进制的程序也一样,直接写test.sh,linux系统会去PATH里寻找有没有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成test.sh是会找不到命令的,要用./test.sh告诉系统“就在当前目录找”。

(3)通过这种方式运行bash脚本,第一行一定要写对,好让系统查找到正确的解释器。

法2、将 Shell 脚本作为参数传递给 Bash 解释器

(1)这种运行方式是,直接运行解释器,其参数就是shell脚本的文件名,如:

xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ /bin/sh test.sh 
What is your name?
xjh
Hello, xjh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ 

(2)这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

如何得知上面这两种方式是开启了新进程呢?

Linux 中的每一个进程都有一个唯一的 ID,称为 PID,使用“$$”变量就可以获取当前进程的 PID。我们首先编写代码如下,并命名为 check.sh:

#!/bin/bash
echo $$  #输出当前进程PID

然后使用以上两种方式来运行 check.sh,可见两者的PID不一样,属于不同的进程。

xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ echo $$
3258      #当前进程的PID
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ./check.sh 
3372      #新进程的PID
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ echo $$
3258      #当前进程的PID
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ /bin/bash check.sh 
3375      #新进程的PID
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$

2、在当前进程中运行Shell脚本

这里需要引入一个新的命令——source 命令。source 是Shell内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。你也可以理解为,source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限,即不要求该文件具有可执行权限。

另外,source命令也叫“点”命令,即“source filename”与“. filename”同样效果。

xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ls
test.sh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ source test.sh 
What is your name?
xjh
Hello, xjh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ sudo chmod 666 test.sh 
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ ls test.sh -l
-rw-rw-rw- 1 root root 93 Feb 24 13:44 test.sh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ source test.sh 
What is your name?
xjh
Hello, xjh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ . test.sh 
What is your name?
xjh	
Hello, xjh
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$

我们也可以利用之前的check.sh来证明“使用source来执行脚本时,是在当前进程中运行脚本”。

xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ echo $$
3258
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ . check.sh 
3258
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$ source check.sh 
3258
xjh@ubuntu:~/iot/embedded_basic/rootfs/tmp$
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门