使用初始命令运行交互式bash子shell,而不立即返回到(“超级”)shell

我想运行一个bash子shell,(1)运行一些命令,(2),然后留在这个子shell中去按我的意思去做。 我可以分别做这些:

  1. 使用-c标志运行命令:

     $> bash -c "ls; pwd; <other commands...>" 

    然而,在命令执行后,它会立即返回到“super”shell。 我也可以运行一个交互式的子shell:

  2. 开始新的bash过程:

     $> bash 

    它不会退出subshel​​l,直到我明确表示…但我不能运行任何初始命令。 我find的最接近的解决scheme是:

     $> bash -c "ls; pwd; <other commands>; exec bash" 

    它可以工作,但不是我想要的方式,因为它在一个子shell中运行给定的命令,然后打开一个单独的子交互。

我想在一条线上做到这一点。 一旦我退出子shell,我应该返回到正常的“超级”shell没有事件。 一定有办法~~

注:我不是问…

  1. 而不是要求在哪里获得bash手册页
  2. 不问如何从文件中读取初始化命令…我知道如何做到这一点,这不是我正在寻找的解决scheme
  3. 对使用tmux或gnu屏幕不感兴趣
  4. 对这样的背景不感兴趣。 也就是说,这个问题是一般性的,而不是为了任何特定的目的
  5. 如果可能的话,我想避免使用这样的解决方法来完成我想要的工作,但要采用“肮脏”的方式。 我只想在一条线上做到这一点。 特别是,我不想做像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以交互模式打开,等待exitclosures。

    如果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。