shell内建命令和外部命令

shell内建命令和外部命令

今天在使用JavaRuntime.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:切换工作目录
原文地址:https://www.cnblogs.com/Spground/p/9567874.html