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

时间:2014-12-20 14:21:53

标签: bash perl

我正在尝试使用~/.bashrc命令在Perl的system中运行别名命令。它只运行一次命令,但是当我运行它两次时,第二次调用作为后台作业运行然后暂停(与按<CTRL-Z>相同),我必须输入fg才能完成命令。例如

use strict;
use warnings;

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

第二个电话永远不会完成。输出为[1]+ Stopped a.pl

注意:

  • 使用任何其他命令替换my_cmd时获得相同的结果,例如ls
  • 似乎不依赖于我的~/.bashrc文件的内容。我试图从中删除所有内容,问题仍然存在。

我使用的是Ubuntu 14.04和Perl版本5.18.2。

更新

为了进行调试,我将~/.bashrc缩减为

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

和我的~/.bash_profile

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

现在正在运行:

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

给出

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

并正在运行

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

给出

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

[1]+  Stopped                 a.pl

3 个答案:

答案 0 :(得分:6)

我认为您应该使用-i(或-l)开关,而不是将--login开关用于交互式shell,这会导致bash的行为就像调用它一样作为登录shell。

默认情况下,使用-l开关不会加载~/.bashrc。根据{{​​1}},在登录shell中,会加载man bash,然后加载从/etc/profile/~/.bash_profile/~/.bash_login找到的第一个文件。在我的系统上,我在~/.profile/中有以下内容,因此加载了~/.bash_profile

~/.bashrc

现在您正在加载# Source .bashrc if [ -f ~/.bashrc ]; then . ~/.bashrc fi ,您需要启用别名的扩展,这在非交互式shell中是关闭的。为此,您可以在设置别名之前添加以下行:

~/.bashrc

答案 1 :(得分:1)

一个随机停止的过程 - 除ctrl-z之外通常是需要STDIN但没有连接的过程。

尝试使用 - 例如passwd &。这将是背景并直接进入'停止'状态。这很可能是你的bash命令发生的事情。 -i明确表示交互式shell,并且您正在尝试使用非交互式方法执行某些操作。

这几乎肯定不是最好的方法,你可能想要做一些与众不同的事情。 bash --login可能更接近您所追求的目标。

答案 2 :(得分:0)

Tom Fenech的回答在Ubuntu 16.04.1 LTS中为我提供了一些补充。在我的〜/ .bashrc文件的顶部,我注释掉了以下部分,以便如果shell不是交互式的(例如,登录shell),仍然会读取〜/ .bashrc。在其他一些版本的Linux上,我没有看到这一节。

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