【问题标题】:Running system command under interactive bash shell在交互式 bash shell 下运行系统命令
【发布时间】:2015-02-19 06:39:01
【问题描述】:

我正在尝试使用 system 命令从 Perl 运行在我的 ~/.bashrc 中具有别名的命令。它只运行一次命令运行良好,但是当我运行它两次时,第二次调用作为后台作业运行,然后暂停(与按 <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

【问题讨论】:

    标签: bash perl


    【解决方案1】:

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

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

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

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

    shopt -s expand_aliases
    

    【讨论】:

      【解决方案2】:

      一个随机停止的进程——除了ctrl-z,通常是它需要STDIN,但没有附加它。

      尝试一下 - 例如passwd &。它会背景并直接进入“停止”状态。这很可能是您的 bash 命令所发生的事情。 -i 明确表示交互式外壳,并且您正试图用它做一些非交互式的事情。

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

      【讨论】:

        【解决方案3】:

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-06-14
          • 2012-10-23
          • 2011-10-15
          • 2015-02-12
          • 2012-05-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多