使用
-c
标志运行命令:$> bash -c "ls; pwd; <other commands...>"
但是,它命令执行后立即返回“ super”外壳。我也可以只运行一个交互式子shell:
开始新的
bash
进程:$> bash
,它不会退出subshell,直到我明确地说出了……但是我不能运行任何初始命令。我找到的最接近的解决方案是:
$> bash -c "ls; pwd; <other commands>; exec bash"
,它可以工作,但不是我想要的方式,因为它在一个子shell中运行给定命令,然后打开单独的一个用于交互。
我想一行完成。退出子外壳后,我应该回到常规的“超级”外壳,而不会发生任何事件。一定有办法~~
NB:我不问的是什么...
不问在哪里获得bash手册页br />不问如何从文件中读取初始化命令...我知道该怎么做,这不是我正在寻找的解决方案
对使用tmux或gnu屏幕不感兴趣
不感兴趣在此方面。也就是说,这个问题是笼统的,而不是出于任何特定目的
,如果可能的话,我想避免使用可实现我想要的目的的变通方法,而是以一种“肮脏”的方式。我只想单行执行此操作。特别是,我不想做类似
xterm -e 'ls'
的操作#1 楼
可以使用临时命名的管道轻松完成此操作:我发现这确实很有用,并且在注释中不太明显,因此我认为应该是它自己的答案。评论
大概这意味着$ HOME / .bashrc不会执行。它必须包含在临时命名管道中。
–Hubro
15年8月4日在21:47
澄清一下,像这样:bash --init-file <(echo“。\” $ HOME / .bashrc \“; ls; pwd”)
–Hubro
15年8月4日在22:02
这太累了,但确实有效。我不敢相信bash不直接支持这一点。
–尼特耶(Pat Niemeyer)
17-2-24在16:07
@Gus ,。是源命令的同义词:ss64.com/bash/source.html。
–乔纳森·波特(Jonathan Potter)
17 Mar 12 '17 at 3:18
有没有一种方法可以使其与用户切换配合使用,例如sudo bash --init-file <(echo“ ls; pwd”)或sudo -iu username bash --init-file <(echo“ ls; pwd”) ?
–jeremysprofile
18年8月21日在18:52
#2 楼
您可以使用临时文件以环形方式执行此操作,尽管它会占用两行:评论
为了获得良好的效果,您可以通过在其中包括rm $ BASH_SOURCE来使临时文件删除。
– Eduardo Ivanec
2012年3月9日17:05
爱德华多,谢谢。那是一个很好的解决方案,但是...您是在说如果不摆弄文件I / O就不可能做到这一点。有明显的原因使我宁愿将此命令保留为自包含命令,因为一旦混合文件,我将不得不开始担心如何制作随机的临时文件,然后再删除它们,就像您提到的那样。如果我要严格的话,这只需要付出更多的努力。因此,需要一种更简约,更优雅的解决方案。
– SABBATINI Luca
2012年3月9日17:20
@SABBATINILuca:我不是在说那样的话。这只是一种方法,而mktemp确实解决了@cjc指出的临时文件问题。 Bash可以支持从stdin读取init命令,但据我所知还不行。 Specyfing-作为init文件并将它们管道传输一半有效,但是Bash然后退出(可能是因为它检测到了管道)。恕我直言,优雅的解决方案是使用exec。
– Eduardo Ivanec
2012年9月9日17:50
这还不覆盖您的常规bash初始化吗? @SABBATINILuca您想以此实现什么,为什么需要生成一个shell自动运行一些命令,然后保持该shell打开?
–user9517
2012年9月9日17:58
这是一个老问题,但是Bash可以使用以下语法创建临时的命名管道:bash --init-file <(echo“ ls; pwd”)。
– Lie Ryan
2014年2月13日14:59
#3 楼
改为尝试以下方法:评论
仅供参考,这会在之后打开一个新的shell,因此,如果任何命令影响当前shell的状态(例如,获取文件),则可能无法正常工作
– ThiefMaster
17年4月8日在14:47
#4 楼
为什么不使用本机子shell?贝壳。基本上,它等效于bash -c "ls; pwd; exec $BASH"
。如果仍然显得冗长,则有两个选择。一种是将此代码片段用作功能:
$ ( ls; pwd; exec $BASH; )
bar foo howdy
/tmp/hello/
bash-4.4$
bash-4.4$ exit
$
另一种是将
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
$
我个人更喜欢
R
的方法,因为无需使用转义字符串。评论
我不确定在OP中使用exec是否有任何麻烦,但是对我来说,这是建议的最佳解决方案,因为它使用普通的bash命令而没有任何字符串转义问题。
–彼得
19年10月1日在9:05
#5 楼
我指的“期望解决方案”是使用Expect编程语言对bash shell进行编程:评论
我想这也将具有在历史记录中注册命令的优势,我错了吗?另外我很好奇在这种情况下是否执行了bashrc / profile?
– muhuk
2015年11月7日10:49
确认这可让您将命令放入历史记录,而其他解决方案则不行。这对于在.screenrc文件中启动进程非常有用-如果退出已启动的进程,则不会关闭屏幕窗口。
–丹·桑德伯格
18-10-29在13:56
#6 楼
如果sudo -E bash
无法正常工作,我将使用到目前为止满足我期望的以下命令: HOME设置为用户的HOME,而不是root的HOME,这在某些系统上默认发生。#7 楼
不如--init-file
优雅,但也许更实用:fn(){
echo 'hello from exported function'
}
while read -a commands
do
eval ${commands[@]}
done
#8 楼
我仅使用脚本即可完成基本相同的操作,通常是为了设置环境变量以在特定项目目录中使用;$ cat shell.sh
#!/bin/bash
export PATH=$PWD/bin:$PATH
export USERNAME=foo
export PASSWORD=bar
export DB_SERVER=http://localhost:6001
bash
$ echo ${USERNAME:-none}
none
$ ./shell.sh
$ echo $USERNAME
foo
进行所有环境调整后,使用交互式
bash
shell;您可以使用要运行的其他相关命令来更新此脚本。 #9 楼
$ bash --init-file <(echo 'ls; pwd')
$ bash --rcfile <(echo 'ls; pwd')
如果无法使用流程替换:
$ cat script
ls; pwd
$ bash --init-file script
与
sh
(dash
,busybox
):$ ENV=script sh
或:
$ bash -c 'ls; pwd; exec bash'
$ sh -c 'ls; pwd; exec sh'
评论
我可以想象有一个Expect解决方案,但这几乎不是您想要的那种。 exec bash解决方案以哪种方式不适合您?@glennjackman抱歉,我对行话不熟悉。什么是“期望解决方案”?另外,exec bash解决方案涉及两个单独的子shell。我想要一个连续的子外壳。
exec的优点在于它将第一个子shell替换为第二个子shell,因此您仅在父级之下保留了1个shell。如果您的初始化命令设置了环境变量,则它们将存在于执行后的shell中。
可能相同的stackoverflow.com/questions/7120426/…
exec的问题在于,您丢失了所有未通过环境传递给子shell的东西,例如未导出的变量,函数,别名,...