我想运行一个 bash 子 shell,(1) 运行一些命令,(2) 然后留在那个子 shell 中按照我的意愿去做。我可以单独做这些:
使用-c标志运行命令:
$> bash -c "ls; pwd; <other commands...>"
Run Code Online (Sandbox Code Playgroud)
但是,它会在命令执行后立即返回到“超级”shell。我也可以只运行一个交互式子shell:
启动新bash进程:
$> bash
Run Code Online (Sandbox Code Playgroud)
它不会退出子shell,直到我明确地说出来......但我无法运行任何初始命令。我找到的最接近的解决方案是:
$> bash -c "ls; pwd; <other commands>; exec bash"
Run Code Online (Sandbox Code Playgroud)
这是可行的,但不是我想要的方式,因为它在一个子 shell 中运行给定的命令,然后打开一个单独的命令进行交互。
我想在一行上做到这一点。一旦我退出子外壳,我应该返回到常规的“超级”外壳,而不会发生任何事故。一定有办法~~
注意:我不是在问什么......
xterm -e 'ls'Jon*_*ter 110
这可以通过临时命名管道轻松完成:
bash --init-file <(echo "ls; pwd")
Run Code Online (Sandbox Code Playgroud)
这个答案归功于Lie Ryan的评论。我发现这真的很有用,而且在评论中不太明显,所以我认为它应该是它自己的答案。
Edu*_*nec 17
您可以使用临时文件以迂回的方式执行此操作,尽管它需要两行:
echo "ls; pwd" > initfile
bash --init-file initfile
Run Code Online (Sandbox Code Playgroud)
小智 12
试试这个:
$> bash -c "ls;pwd;other commands;$SHELL"
Run Code Online (Sandbox Code Playgroud)
$SHELL 它使外壳以交互模式打开,等待关闭exit。
为什么不使用本机子 shell?
$ ( ls; pwd; exec $BASH; )
bar foo howdy
/tmp/hello/
bash-4.4$
bash-4.4$ exit
$
Run Code Online (Sandbox Code Playgroud)
用括号括住命令会使 bash 生成一个子进程来运行这些命令,因此您可以在不影响父 shell 的情况下更改环境。这基本上相当于bash -c "ls; pwd; exec $BASH".
如果这看起来仍然很冗长,有两种选择。一种是将此代码片段作为函数:
$ run() { ( eval "$@"; exec $BASH; ) }
$ run 'ls; pwd;'
bar foo howdy
/tmp/hello/
bash-4.4$ exit
$ run 'ls;' 'pwd;'
bar foo howdy
/tmp/hello/
bash-4.4$ exit
$
Run Code Online (Sandbox Code Playgroud)
另一种方法是exec $BASH缩短:
$ R() { exec $BASH; }
$ ( ls; pwd; R )
bar foo howdy
/tmp/hello/
bash-4.4$ exit
$
Run Code Online (Sandbox Code Playgroud)
我个人R更喜欢这种方法,因为不需要使用转义字符串。
我指的“Expect 解决方案”是使用Expect 编程语言编写 bash shell :
#!/usr/bin/env expect
set init_commands [lindex $argv 0]
set bash_prompt {\$ $} ;# adjust to suit your own prompt
spawn bash
expect -re $bash_prompt {send -- "$init_commands\r"}
interact
puts "exiting subshell"
Run Code Online (Sandbox Code Playgroud)
你可以这样运行:./subshell.exp "ls; pwd"
小智 5
您需要执行启动脚本,然后继续进行交互式会话。
默认启动脚本是~/.bashrc,可以通过选项指定另一个脚本--init-file。如果您只是传递一个--init-file选项,您的脚本将替换默认值,而不是增强它。
解决方案是使用<(...)语法传递一个临时脚本,该脚本来源默认值,~/.bashrc后跟任何其他命令:
bash --init-file <(echo ". ~/.bashrc; ls; pwd; ### other commands... ###")
Run Code Online (Sandbox Code Playgroud)