我想运行一个bash子shell,(1)运行一些命令,(2),然后留在这个子shell中去按我的意思去做。 我可以分别做这些:
使用-c
标志运行命令:
$> bash -c "ls; pwd; <other commands...>"
然而,在命令执行后,它会立即返回到“super”shell。 我也可以运行一个交互式的子shell:
开始新的bash
过程:
$> bash
它不会退出subshell,直到我明确表示…但我不能运行任何初始命令。 我find的最接近的解决scheme是:
$> bash -c "ls; pwd; <other commands>; exec bash"
它可以工作,但不是我想要的方式,因为它在一个子shell中运行给定的命令,然后打开一个单独的子交互。
我想在一条线上做到这一点。 一旦我退出子shell,我应该返回到正常的“超级”shell没有事件。 一定有办法~~
注:我不是问…
xterm -e 'ls'
这可以通过临时命名pipe道轻松完成:
bash --init-file <(echo "ls; pwd")
这个答案的信贷来自Lie Ryan的评论。 我发现这真的很有用,而且在评论中不太明显,所以我认为这应该是它自己的答案。
你可以用一个临时文件以一种迂回的方式做到这一点,虽然它会占用两行:
echo "ls; pwd" > initfile bash --init-file initfile
我所指的“期望解决scheme”是用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"
你会像这样运行: ./subshell.exp "ls; pwd"
试试这个:
$> bash -c "ls;pwd;other commands;$SHELL"
$SHELL
它使shell以交互模式打开,等待exit
closures。
如果sudo -E bash
不起作用,我使用以下,迄今已达到我的预期:
sudo HOME=$HOME bash --rcfile $HOME/.bashrc
我设置HOME = $ HOME,因为我希望我的新会话将HOME设置为我的用户的HOME,而不是root的HOME,这在某些系统上默认会发生。
不如--init-file
优雅,但也许更--init-file
:
fn(){ echo 'hello from exported function' } while read -a commands do eval ${commands[@]} done
为什么不使用本机子壳?
$ ( ls; pwd; exec $BASH; ) bar foo howdy /tmp/hello/ bash-4.4$ bash-4.4$ exit $
用圆括号括起命令使bash产生一个subprocess来运行这些命令,所以你可以改变环境而不影响父shell。 这基本上比bash -c "ls; pwd; exec $BASH"
更具可读性。
如果仍然看起来很冗长,有两个select。 一个是把这个片段作为一个函数:
$ 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 $
另一个是使exec $BASH
更短:
$ R() { exec $BASH; } $ ( ls; pwd; R ) bar foo howdy /tmp/hello/ bash-4.4$ exit $
我个人更喜欢R
方法,因为没有必要玩逃避的string。