Analysis
The code you (or rather gnome-terminal
in your case) provides to /bin/sh -c
will see positional parameters provided after the code. E.g. this
gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' zeroth first second …
will print remember: first
.
Providing nothing after the code causes $1
(or $2
, $3
etc.) expand to an empty string when the code is finally interpreted ($0
is somewhat different but this doesn't matter here). This is the reason you got remember:
. /bin/sh
run by gnome-terminal
simply knows nothing about the positional parameters of the main script, unless you pass them explicitly.
Solution
To populate positional parameters of the inner code with positional parameters of the script, use "$@"
instead of first second …
:
gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' sh "$@"
You can pass whatever you want. Here we pass all the parameters ("$@"
expands to all positional parameters), but in general you can use "$1"
(if you want the inner code to know the first parameter only) or "$2"
(if you want the inner code to see the second positional parameter of the main script as its own $1
).
Notes
sh
as the zeroth argument is explained here: What is the second sh in sh -c 'some shell code' sh
?
If in your original script (i.e. without my fix) the shell code you intend to provide to sh -c
was double-quoted, then the shell interpreted the script would expand $1
and embed the result in the inner code. Don't do this though.
# flawed
gnome-terminal -- /bin/sh -c "echo 'remember: $1'; exec bash"
In many cases this would work as you expect; but not in general. In general it is as flawed as embedding {}
. Single quoted-code and arguments after it are the right way.
Single-quoting the code ensures it will get to /bin/sh -c
as-is (the inner double-quotes don't matter). Then sh
will see the code as
echo "remember: $1"; exec bash
and it's very good you double-quoted $1
here.
sh -c
command, they'd use$*
. E.g.gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' sh "$*"
would allow running the script asremind.sh pick up the package
without the quotes (as long as they don't use shell special characters in the message that would need quoting) – ilkkachu May 22 '22 at 16:03