4

Here is my script:

echo "Defining aliases"
echo $$
echo "
s=screen
v=vlock -a
j=jobs
" | sed '/^$/d' | while read alias
do
  echo $$
  alias "$alias"
  alias | wc -l
done

And here is its output:

parthian@computer$ . aliases 
Defining aliases
3744
3744
4
3744
5
3744
6
parthian@computer$ ps -p $$
PID TTY          TIME CMD
3744 pts/1    00:00:03 bash
parthian@computer$ alias | wc -l
3

I'm flummoxed. This is some of the most straightforward code I've ever written, and it's not doing what it's supposed to do.

EDIT: When I change the echo lines from echo $$ to echo $$ $BASHPID, the second PID ($BASHPID) is different inside the loop, but $$ remains the same throughout. Could this be the issue?

2
  • And it can't be that I'm not making enough blood sacrifices to Stallman's beard, because I sacrificed my last oxen just yesterday. Commented Jun 24, 2015 at 23:33
  • 1
    By putting the alias definitions on the RHS of a pipe (... | while read ...), you are implicitly confining their scope to a subshell, I think: see mywiki.wooledge.org/BashFAQ/024 Commented Jun 24, 2015 at 23:44

1 Answer 1

4

Don’t believe everything a computer tells you.

$ ps -p $$
PID TTY          TIME CMD
3744 pts/1    00:00:03 bash
$ ps -t pts/1
PID TTY          TIME CMD
3744 pts/1    00:00:03 bash
4285 pts/1    00:00:00 ps
$ echo foo | while read x
do
        ps -t pts/1
done
PID TTY          TIME CMD
3744 pts/1    00:00:03 bash
4287 pts/1    00:00:00 bash
4288 pts/1    00:00:00 ps
$ echo "$$, $BASHPID"
3744, 3744
$ echo foo | while read x
do
        echo "$$, $BASHPID"
        ps -t pts/1
done
3744, 4292
PID TTY          TIME CMD
3744 pts/1    00:00:03 bash
4292 pts/1    00:00:00 bash
4293 pts/1    00:00:00 ps

When you do some_command | while …, the shell puts the while loop into a subshell, but $$ continues to report the PID of the main (parent) process.  In bash, $BASHPID reveals the truth.

Consider doing

while read alias
do
  alias "$alias"
done << EOF
s=screen
v=vlock -a
j=jobs
EOF
3
  • Arrghhh.  I didn't see your edit until I had finished typing my answer.  Hope it helps anyway. Commented Jun 25, 2015 at 0:02
  • It does. Seems silly, but it hadn't occurred to me to use a heredoc- thanks! Commented Jun 25, 2015 at 0:16
  • 1
    It is also mentioned in bash man page: "[$]$ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell." May be it also applies to subshells created for pipes Commented Jun 25, 2015 at 1:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.