简体   繁体   English

在交互式bash shell下运行系统命令

[英]Running system command under interactive bash shell

I am trying to run a command that has been aliased in my ~/.bashrc from Perl using the system command. 我正在尝试使用system命令运行一个在Perl的~/.bashrc别名的命令。 It works well running the command only once, but when I run it twice the second invocation is run as a background job and then suspended (the same as pressing <CTRL-Z> ) and I have to type fg to complete the command. 它只能运行一次命令,但是当我运行它两次时,第二次调用作为后台作业运行然后暂停(与按<CTRL-Z> ),我必须输入fg才能完成命令。 For example 例如

use strict;
use warnings;

system ('bash -ic "my_cmd"');
system ('bash -ic "my_cmd"');

The second call never completes. 第二个呼叫永远不会完成。 The output is [1]+ Stopped a.pl . 输出为[1]+ Stopped a.pl

Note: 注意:

  • The same result is obtained when replacing my_cmd with any other command, for example ls . my_cmd替换为任何其他命令(例如ls时获得相同的结果。
  • It seems not to depend of the contents of my ~/.bashrc file. 它似乎不依赖于我的~/.bashrc文件的内容。 I tried to remove everything from it, and the problem still persisted. 我试图从中删除所有内容,问题仍然存在。

I am using Ubuntu 14.04 and Perl version 5.18.2. 我使用的是Ubuntu 14.04和Perl版本5.18.2。

Update 更新

For debugging I reduced my ~/.bashrc to 为了调试我将~/.bashrc缩减为

echo "Entering ~/.bashrc .."
alias my_cmd="ls"
alias

and my ~/.bash_profile to 和我的~/.bash_profile

if [ -f ~/.bashrc ]; then
    echo "Entering ~/.bash_profile .."
    . ~/.bashrc
fi

Now running: 现在运行:

system ('bash -lc "my_cmd"');
system ('bash -lc "my_cmd"');

gives

Entering ~/.bash_profile ..
Entering ~/.bashrc ..
alias my_cmd='ls'
bash: my_cmd: command not found
Entering ~/.bash_profile ..
Entering ~/.bashrc ..
alias my_cmd='ls'
bash: my_cmd: command not found

and running 并运行

system ('bash -ic "my_cmd"');
system ('bash -ic "my_cmd"');

gives

Entering ~/.bashrc ..
alias my_cmd='ls'
a.pl  p.sh

[1]+  Stopped                 a.pl

Rather than using the -i switch for an interactive shell, I think you should use the -l (or --login ) switch, which causes bash to act as if it had been invoked as a login shell. 我认为您应该使用-l (或--login )开关,而不是将-i开关用于交互式shell,这会导致bash的行为就好像它已被作为登录shell调用一样。

Using the -l switch doesn't load ~/.bashrc by default. 默认情况下,使用-l开关不会加载~/.bashrc According to man bash , in a login shell, /etc/profile/ is loaded, followed by the first file found from ~/.bash_profile/ , ~/.bash_login or ~/.profile/ . 根据man bash ,在登录shell中,加载/etc/profile/ ,然后加载从~/.bash_profile/~/.bash_login~/.profile/找到的第一个文件。 On my system, I have the following in ~/.bash_profile , so ~/.bashrc is loaded: 在我的系统上,我在~/.bash_profile有以下内容,所以~/.bashrc被加载:

# Source .bashrc
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

Now that your ~/.bashrc is being loaded, you need to enable the expansion of aliases, which is off in a non-interactive shell. 现在您正在加载~/.bashrc ,您需要启用别名的扩展,这在非交互式shell中是关闭的。 To do this, you can add the following line before setting your aliases: 为此,您可以在设置别名之前添加以下行:

shopt -s expand_aliases

A process randomly stopping - aside from ctrl-z is usually when it needs STDIN, but doesn't have it attached. 一个随机停止的过程 - 除了ctrl-z通常是需要STDIN但没有附加它。

Try it with - for example passwd & . 尝试使用 - 例如passwd & It'll background and go straight into 'stopped' state. 这将是背景并直接进入'停止'状态。 This may well be what's happening with your bash command. 这很可能是你的bash命令发生的事情。 -i means interactive shell, explicitly, and you're trying to do something noninteractive with it. -i意味着交互式shell,显然,你正试图用它做一些非交互式的东西。

That's almost certainly not the best approach, you probably want to do something different. 这几乎肯定不是最好的方法,你可能想要做一些与众不同的事情。 bash --login might be closer to what you're after. bash --login可能更接近你所追求的。

Tom Fenech's answer worked for me in Ubuntu 16.04.1 LTS with a small addition. Tom Fenech的回答在Ubuntu 16.04.1 LTS中为我提供了一些补充。 At the top of my ~/.bashrc file, I commented out the following section so that if the shell is not interactive (eg, a login shell), ~/.bashrc is still read. 在〜/ .bashrc文件的顶部,我注释掉了以下部分,这样如果shell不是交互式的(例如,登录shell),仍然会读取〜/ .bashrc。 On some other versions of Linux I don't see this section. 在其他一些版本的Linux上,我没有看到这一节。

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 git-bash 下的 python 中运行 shell 命令效果不佳 - running shell command in python under git-bash not working well Bash 命令在交互式 shell 中有效,但在脚本中无效 - Bash command works in interactive shell but not in script 在 shell 脚本中将交互式命令作为后台进程运行 - Running a interactive command as a background process in shell script Bash命令以bash -c失败,但可在交互式shell中使用 - Bash command fails with bash -c but works in an interactive shell 将 bash shell 脚本的输出作为 shell 命令运行? - Running the output of a bash shell script as a shell command? 通过bash脚本在交互式ncat shell中运行命令 - Run command in interactive ncat shell via bash script 使用初始命令在Ruby脚本中启动交互式Bash Shell - Launch interactive Bash shell in Ruby script, with initial command -bash: ghci: command not found (Haskell interactive shell, Haskell 安装) - -bash: ghci: command not found (Haskell interactive shell, Haskell installation ) 在bash / python / perl脚本中运行一系列交互式shell命令 - running series of interactive shell commands in bash/python/perl script Bash 打开 Shell 的脚本,运行 Shell 中的命令,并保持 Shell 运行 - Bash Script to Open a Shell, Run a Command in the Shell, & Keep Shell Running
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM