我的理解是,当我使用$ ./myscript.sh
这样的语法在BASH shell中执行脚本时,会启动一个子shell,代码在该shell中运行,STDOUT和STDERR输出被打印在我的shell上,STDIN是从我的shell中获取的。这就是脚本交互的方式。
文件“myscript”的第一行是#!/bin/bash
,这说明了用于执行脚本文件中语法的解释器。
如果我使用语法source myscript.sh
,脚本中的代码将被“拉”到当前环境中并在那里执行,而不是在子shell中执行。我不能让下面的代码在我用$ ./myscript.sh
调用的脚本中运行,并影响我当前的shell:
#!/bin/bash
PS1='`
if [ $? -eq 0 ];
then echo -n "\[\033[00;35m\]\u\[\033[01;32m\]@\[\033[00;35m\]\h\[\033[00;32m\](\[\033[01;35m\]\W\[\033[01;32m\])\[\033[00;32m\]\$";
else echo -n "\[\033[00;35m\]\u\[\033[01;31m\]@\[\033[00;35m\]\h\[\033[01;31m\](\[\033[35m\]\W\[\033[31m\])\[\033[00;31m\]\$";
fi`\[\033[0m\]'
如果我删除#!/bin/bash
并使用source
,此脚本将更改我的命令提示符。是否可以将它安排在脚本中,使我可以用$ ./myscript.sh
调用它,并且它将更改我当前的shell,而不是子shell?
2条答案
按热度按时间2fjabf4q1#
一旦你调用了一个没有
source
的脚本,它就运行在一个子shell中,没有办法改变父shell的环境。您可以使用shebang行来源化脚本。它只是在源代码时被忽略。
q5lcpyga2#
我不太确定你想做什么,所以我不认为我能解决你的问题(我不知道
$?
是如何设置的)。也就是说,我今天刚刚发现的可能会帮助有类似问题的人。OP的脚本无法实现其目的,因为它试图应用的更改在子shell退出时丢失。我以前已经为此挣扎过好几次了,今天又和它搏斗了。我想出了一个不同的方法,重写脚本以 * 生成 * 但 * 不应用 * 参数。
为了解决OP的困难,创建以下脚本,它遵循OP脚本的精神(我随意使用了提示字符串和条件语句):
然后调用它:
请注意,这也适用于需要多个参数的命令。在我的例子中,脚本最初使用三个计算参数调用
enable
,它以熟悉的方式失败了。我重写了该脚本,以便只输出三个计算参数,并将该脚本安装在/usr/local/bin
中,以方便访问。使用该脚本为enable
提供参数,而不必提供复杂的路径,这使得使用我的内建更加用户友好。