Reputation: 40778
I am trying to run a command that has been aliased in my ~/.bashrc
from Perl using the system
command. 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. 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
.
Note:
my_cmd
with any other command, for example ls
.~/.bashrc
file. I tried to remove everything from it, and the problem still persisted.I am using Ubuntu 14.04 and Perl version 5.18.2.
Update
For debugging I reduced my ~/.bashrc
to
echo "Entering ~/.bashrc .."
alias my_cmd="ls"
alias
and my ~/.bash_profile
to
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
Upvotes: 5
Views: 1439
Reputation: 498
Tom Fenech's answer worked for me in Ubuntu 16.04.1 LTS with a small addition. At the top of my ~/.bashrc file, I commented out the following section so that if the shell is not interactive (e.g., a login shell), ~/.bashrc is still read. On some other versions of Linux I don't see this section.
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Upvotes: 0
Reputation: 74695
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.
Using the -l
switch doesn't load ~/.bashrc
by default. 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/
. On my system, I have the following in ~/.bash_profile
, so ~/.bashrc
is loaded:
# 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. To do this, you can add the following line before setting your aliases:
shopt -s expand_aliases
Upvotes: 6
Reputation: 53508
A process randomly stopping - aside from ctrl-z
is usually when it needs STDIN, but doesn't have it attached.
Try it with - for example passwd &
. It'll background and go straight into 'stopped' state. This may well be what's happening with your bash command. -i
means interactive shell, explicitly, and you're trying to do something noninteractive with it.
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.
Upvotes: 1