shell内建命令和外部命令
shell内建命令和外部命令
今天在使用Java
的Runtime.exe()
执行一个Linux
命令的时候,出现了错误,通过问题的解决学习到了shell的内建命令和外部命令的差别。
问题:
使用如下Java
代码执行一个命令的时候,报错提示说:不能运行source
命令,原因是不存在该文件或目录。
String cmd = "source activate tensorflow";
Process pr = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
pr.waitFor();
我将前面代码中的cmd修改为cmd = "ls -l"
,发现能正常运行。
百思不得其解,本来对linux不是很熟悉,通过搜索引擎找到了答案,https://stackoverflow.com/questions/7353989/running-process-builder-attempting-to-execute-source-command。
原来,source
命令是shell
的一个built-in
命令,当我在一个java
进程中以Runtime
的方式去执行一个命令时候,实际上是新开了一个子进程sub
去执行该命令,而这个sub
进程不是shell
进程,因此只能执行非shell
内建命令(关于常见的内建命令后面会总结)。
shell
是一个程序,允许我们通过它和操作系统进行交互,当我们在shell中执行的是内建命令,该命令直接在shell进程中执行,而如果执行的是外部命令,shell进程则会fork
出一个新的子进程来执行外部命令。
所以内建命令能够被执行的前提是需要存在一个shell进程。
内建命令和外部命令
shell内建命令是shell程序提供的一些命令,而外部命令是其他独立的程序(这些独立的程序和shell同级)。
通常我们在shell中直接输入一个命令,我们并不能直接看出这些命令哪些是内建命令,哪些是外部命令?
例如:
cd /root
和
ls -l
以上我们无法区分哪个是内建命令(cd
是shell内建命令,ls
是外部命令)。
那么如何怎么判断哪些命令是内建命令还是外部命令呢?
通常使用which name
或者type name
即可判断得出。
例如
1.
which mkdir
输出
/bin/mkdir
-
2.
which source
输出
source: shell built-in command
如何使用内建命令
内建命令可以紧跟shell命令后面,让shell程序去解释执行该命令。
形如:
sh cmd-name
bash cmd-name
zsh cmd-name
另外常见的shell还可以增加一些参数,例如
bash -c "ls -l"
常见的shell参数:
-c string:命令从-c后的字符串读取。
-i:实现脚本交互。
-n:进行shell脚本的语法检查。
-x:实现shell脚本逐条语句的跟踪。
常见的shell内建命令
- source:在当前bash环境下读取并执行指定的命令
- echo:输出指定的字符串或者变量
- type:显示指定命令的类型
- env:显示系统中已存在的环境变量
- exec:调用并执行指定的命令
- kill:删除执行中的程序或工作
- alias:用来设置指令的别名
- unalias:用来删除指令的别名
- exit:退出当前的shell
- jobs:显示linux的任务列表和状态
- history:显示历史命令
- logout:退出当前登录的shell
- export:设置或者显示当前登录的shell
- cd:切换工作目录