这可能是非常简单或者非常复杂的问题,但我没有找到任何相关内容... 我正在尝试打开一个新的Bash实例,然后在其中运行一些命令,并将控制权交回给用户,在同一实例内。
我已经尝试过:
$ bash -lic "some_command"
但是这个命令会在新的实例中执行 some_command
,然后关闭它。我希望它保持打开状态。
还有一个细节可能会影响答案:如果我能让它工作,我将在我的.bashrc
中使用它作为别名,因此对于别名的实现方法会额外加分!
bash --rcfile <(echo '. ~/.bashrc; some_command')
释放临时文件的创建。其他网站上的问题:
cat ~/.bashrc
是否有效?2)cat <(echo a)
是否有效?3)bash --rcfile somefile
是否有效? - Ciro Santilli OurBigBook.combash.exe --rcfile ^<^(echo 'source $HOME/.bashrc; ls; pwd'^)
应该可以从Windows命令提示符中运行。 - user2561747sudo bash --init-file <(echo "ls; pwd")
或 sudo -iu username bash --init-file <(echo "ls; pwd")
? - jeremysprofilebash --rcfile myrcfile
。在文件内容中,您有. ~/.bashrc; some_command
。 - eglasius虽然有些晚了,但我遇到了完全相同的问题,谷歌把我带到这个页面,为了完整起见,这里是我如何解决这个问题的。
据我所知,bash
没有选项可以实现原帖想要做的事情。 -c
选项将在命令执行后立即返回。
错误的解决方案:最简单和显而易见的尝试是:
bash -c 'XXXX ; bash'
这部分有点用(尽管多了一个子Shell层)。 然而,问题在于虽然子Shell会继承导出的环境变量,但别名和函数却不会被继承。 因此,这可能对一些东西有效,但并不是通用解决方案。
更好的方法:绕过这个问题的方法是动态创建一个启动文件,并使用这个新的初始化文件调用bash,确保您的新init文件在必要时调用您的常规~/.bashrc
文件。
# Create a temporary file
TMPFILE=$(mktemp)
# Add stuff to the temporary file
echo "source ~/.bashrc" > $TMPFILE
echo "<other commands>" >> $TMPFILE
echo "rm -f $TMPFILE" >> $TMPFILE
# Start the new bash shell
bash --rcfile $TMPFILE
好处在于临时的初始化文件会在被使用后自动删除,减少了没有正确清理的风险。
注意:我不确定 /etc/bashrc 是否通常作为普通非登录 shell 的一部分调用。 如果是这样,您可能需要同时源 /etc/bashrc 和您的 ~/.bashrc
。
rm -f $TMPFILE
这个东西很好用。我实际上不记得我当时使用它的用例,现在我使用更先进的自动化技术,但这仍然是正确的方法! - Félix Saparellibash --rcfile <(echo ". ~/.bashrc; a=b")
不会生成临时文件。 - Ciro Santilli OurBigBook.com--rcfile
,使其读取您选择的文件。这个文件将代替您的.bashrc
。(如果有问题,请从其他脚本中源代码~/.bashrc
)。~/.more.sh
的内容启动新shell的函数将如下所示:more() { bash --rcfile ~/.more.sh ; }
在.more.sh
中,您可以编写希望在shell启动时执行的命令。(我认为避免使用单独的启动文件会更加优雅-- 您不能使用标准输入,因为那样shell就不会是交互式的,但是您可以从临时位置创建一个here文档的启动文件,然后读取它。)
bash -c '<some command> ; exec /bin/bash'
避免额外的shell子层
bash -c 'alias xxx=yyy; exec bash'
命令,它不会起作用。别名是局部的,不会传递给子 bash。 - anton_rhshortcut () { yourterminal -e "bash -c '$@'; exec /bin/bash"; }
尽管这个命令会在具有文字单引号的情况下出现问题。 - tripleee这个被接受的答案非常有帮助! 只是要补充说明,一些shell不支持进程替换(例如dash
)。
在我的情况下,我试图在Thunar文件管理器中创建一个自定义操作 (基本上是一行shell脚本),以启动一个shell并激活选定的Python虚拟环境。我的第一次尝试是:
urxvt -e bash --rcfile <(echo ". $HOME/.bashrc; . %f/bin/activate;")
其中%f
是由Thunar处理的虚拟环境路径。
我运行Thunar时遇到了错误(通过命令行):
/bin/sh: 1: Syntax error: "(" unexpected
然后我意识到我的sh
(基本上是dash
)不支持进程替换。
我的解决方案是在顶层调用bash
来解释进程替换,代价是增加了一个额外的shell层:
bash -c 'urxvt -e bash --rcfile <(echo "source $HOME/.bashrc; source %f/bin/activate;")'
另外,我尝试使用 here-document 用于 dash
,但没有成功。大致如下:
echo -e " <<EOF\n. $HOME/.bashrc; . %f/bin/activate;\nEOF\n" | xargs -0 urxvt -e bash --rcfile
附言:我没有足够的声望来发布评论,请管理员将其移动到评论区或者如果对这个问题不帮助请删除。
您可以通过源代码来获取想要的功能而不是运行它。例如:
$cat script cmd1 cmd2 $ . script $此时,cmd1和cmd2已经在这个shell内运行了。
在~/.bashrc
中添加类似以下内容的部分:
if [ "$subshell" = 'true' ]
then
# commands to execute only on a subshell
date
fi
alias sub='subshell=true bash'
然后你可以使用sub
启动子shell。
grep -nrs --color -w --include="*.{h,c}" Testing ./
bash
grep -nrs --color -w --include="*.{h,c}" Testing ./
exit
echo 'grep -nrs --color -w --include="*.{h,c}" Testing ./' > tmp_file.txt
bash tmp_file.txt
bash -c 'grep -nrs --color -w --include="*.{h,c}" Testing ./'
alias ebash './execute_command_on_bash.sh'
ebash grep -nrs --color -w --include="*.{h,c}" Testing ./
#!/bin/bash
# =========================================================================
# References:
# https://dev59.com/QG435IYBdhLWcg3wrSLN#13343457
# https://dev59.com/LG865IYBdhLWcg3wkPWD#26733366
# https://dev59.com/yHE85IYBdhLWcg3wShaf#2853811
# https://dev59.com/yHE85IYBdhLWcg3wShaf#2853811
# https://www.linuxquestions.org/questions/other-%2Anix-55/how-can-i-run-a-command-on-another-shell-without-changing-the-current-shell-794580/
# https://www.tldp.org/LDP/abs/html/internalvariables.html
# https://dev59.com/sG855IYBdhLWcg3wjlCL#4277753
# =========================================================================
# Enable following line to see the script commands
# getting printing along with their execution. This will help for debugging.
#set -o verbose
E_BADARGS=85
if [ ! -n "$1" ]
then
echo "Usage: `basename $0` grep -nrs --color -w --include=\"*.{h,c}\" Testing ."
echo "Usage: `basename $0` find . -name \"*.txt\""
exit $E_BADARGS
fi
# Create a temporary file
TMPFILE=$(mktemp)
# Add stuff to the temporary file
#echo "echo Hello World...." >> $TMPFILE
#initialize the variable that will contain the whole argument string
argList=""
#iterate on each argument
for arg in "$@"
do
#if an argument contains a white space, enclose it in double quotes and append to the list
#otherwise simply append the argument to the list
if echo $arg | grep -q " "; then
argList="$argList \"$arg\""
else
argList="$argList $arg"
fi
done
#remove a possible trailing space at the beginning of the list
argList=$(echo $argList | sed 's/^ *//')
# Echoing the command to be executed to tmp file
echo "$argList" >> $TMPFILE
# Note: This should be your last command
# Important last command which deletes the tmp file
last_command="rm -f $TMPFILE"
echo "$last_command" >> $TMPFILE
#echo "---------------------------------------------"
#echo "TMPFILE is $TMPFILE as follows"
#cat $TMPFILE
#echo "---------------------------------------------"
check_for_last_line=$(tail -n 1 $TMPFILE | grep -o "$last_command")
#echo $check_for_last_line
#if tail -n 1 $TMPFILE | grep -o "$last_command"
if [ "$check_for_last_line" == "$last_command" ]
then
#echo "Okay..."
bash $TMPFILE
exit 0
else
echo "Something is wrong"
echo "Last command in your tmp file should be removing itself"
echo "Aborting the process"
exit 1
fi
$ bash --init-file <(echo 'some_command')
$ bash --rcfile <(echo 'some_command')
如果你不能或不想使用进程替换:
$ cat script
some_command
$ bash --init-file script
$ bash -c 'some_command; exec bash'
$ sh -c 'some_command; exec sh'
sh
-only 方式(dash
,busybox
):
$ ENV=script sh
ENV=script
之前)删除或重新措辞,以避免被误认为是明显的复制粘贴顶部答案。 - Félix SaparelliENV
+ sh
的解决方案以外,其他答案中都有这些解决方案,但是它们通常被大量的文本埋没或者被不必要/非必要的代码包围。我认为提供一个简明清晰的摘要对每个人都有好处。 - x-yuri这里是另一种(可行的)变体:
它打开一个新的 GNOME 终端,然后在新终端中运行 bash。首先读取用户的 rc 文件,然后将命令 ls -la
发送到新 shell 中执行,然后再转为交互模式。
最后的 echo 添加了一个额外的换行符,以完成执行。
gnome-terminal -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'
有时我也觉得在终端上添加一些装饰很有用,比如使用颜色来更好地定位。
gnome-terminal --profile green -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'
alias shortcut='bash -lic "some_command"'
的内容,然后运行shortcut
命令,就可以打开一个新的 shell 并自动执行some_command
。 - Félix Saparelli