-4

Please help to see if there is someway to make below scrip workable?

name='bob'
# below script reports 'bash: !: event not found' error
sh -c "echo $name; sleep 20 & pid1=$!; sleep 10 & pid2=$!; echo \"pid1: $pid1, pid2: $pid2\"" 
# below script $name will not become bob
sh -c 'echo $name; sleep 20 & pid1=$!; sleep 10 & pid2=$!; echo \"pid1: $pid1, pid2: $pid2\"' 

[Add 01/03]

This question is somewhat duplicate of this one, it's my fault that the description of the original question is not clear and accurate enough, and I try to create a new one to make it more specific and clear.

Y.Huang
  • 119
  • 2
  • 11

2 Answers2

1

You seem to be trying to solve the event not found problem.

It happens when you have set -H in Bash and use an exclamation mark in an interactive command (outside of single quotes or a backslash escape).

I have posted an answer and I think half a dozen comments explaining what is happening and how to fix it.

set +H

This command disables the Bash history mechanism which uses the exclamation mark in interactive sessions.

In addition, within double quotes, you have to escape the dollar sign to pass it verbatim to the subshell.

sh -c "echo \"$name\"
    sleep 20 & pid1=\$!
    sleep 10 & pid2=\$!
    echo \"pid1: \$pid1, pid2: \$pid2\"" 
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • This isn't a proper answer but I'm hoping at least this will prompt you to clarify if this precise problem is not the one you are still trying to solve. Otherwise please accept the duplicate I proposed. – tripleee Jan 02 '18 at 13:55
  • I am afraid maybe I didn't catch your point, actually I want to store `$!` as PID number to a variable and use it later, the `event not found` is a side-error I encountered for my script: `sh -c "echo $name; sleep 20 & pid1=$!; sleep 10 & pid2=$!; echo \"pid1: $pid1, pid2: $pid2\""`, and if I use `set +H; sh -c "echo $name; sleep 20 & pid1=$!; sleep 10 & pid2=$!; echo \"pid1: $pid1, pid2: $pid2\""`, there is no `event not found` error, but `$!` doesn't convert to PID number what I want to get. – Y.Huang Jan 03 '18 at 02:27
  • Uplated answer. Though this is basically a duplicate of https://stackoverflow.com/a/37746186/874188 – tripleee Jan 03 '18 at 04:32
1

The comments propose mixing quotes and disabling history expansion, but a better solution (IMO) is to pass the name as a parameter:

sh -c 'echo "$1"; sleep 20 & pid1=$!; ...' sh "$name"
William Pursell
  • 204,365
  • 48
  • 270
  • 300