<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Passing shell script arguments to a subprocess - comments</title>
    <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comments</link>
    <description>Comments on "Passing shell script arguments to a subprocess" by Yossi Kreinin</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>Yossi Kreinin's ugly publishing software</generator>
    <image>
      <url>https://yosefk.com/blog/self.jpg</url>
      <title>Passing shell script arguments to a subprocess - comments</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comments</link>
      <width>144</width>
      <height>144</height>
    </image>
    <language>en</language>
    <lastBuildDate>Sat, 27 Jun 2026 04:00:08 +0000</lastBuildDate>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-2929</link>
      <description><![CDATA[<html><head>
</head><body><p>Thanks! Yeah, I've seen — passed to every other command in git's
shell source code... "Do one job and do it well..."</p>
]]></description>
      <pubDate>Sun, 10 Jan 2016 22:08:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>dzan</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-2928</link>
      <description><![CDATA[<html><head>
</head><body><p>Previous samles with 'set' work fine but marke sure to use</p>
<p>set — "$@" "$arg"</p>
<p>Otherwise if the first argument is a valid one for set it will use
it, e.g. -x.</p>
<p></p>]]></description>
      <pubDate>Sun, 10 Jan 2016 12:35:00 +0000</pubDate>
      <dc:creator>dzan</dc:creator>
    </item>
    <item>
      <title>Eduardo Bustamante</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-2774</link>
      <description><![CDATA[<html><head>
</head><body><p>This is safer and more straightforward than using eval:</p>
<p>dualbus@yaqui ~ % ./args.sh foo bar baz<br>
foo barbar bazbaz<br>
dualbus@yaqui ~ % cat args.sh<br>
#!/bin/sh</p>
<p>ENV_VAR=value;<br>
export ENV_VAR</p>
<p>nargs=$#<br>
for arg do<br>
case $arg in<br>
*[abc]*) arg=$arg$arg;;<br>
esac</p>
<p>set "$@" "$arg"<br>
done</p>
<p>shift "$nargs"</p>
<p>echo "$@"</p>
<p># In case this doesn't show correctly here:<br>
# <a href="http://dualbus.sdf.org/s/a7832dc9.txt" rel="nofollow">http://dualbus.sdf.org/s/a7832dc9.txt</a></p>
<p></p>]]></description>
      <pubDate>Fri, 08 May 2015 19:08:00 +0000</pubDate>
      <dc:creator>Eduardo Bustamante</dc:creator>
    </item>
    <item>
      <title>ahervert</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-2770</link>
      <description><![CDATA[<html><head>
</head><body><p>nfomon that is the solution</p>
<p></p>]]></description>
      <pubDate>Thu, 07 May 2015 02:37:00 +0000</pubDate>
      <dc:creator>ahervert</dc:creator>
    </item>
    <item>
      <title>Bilal</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-2673</link>
      <description><![CDATA[<html><head>
</head><body><p>You save my day!</p>
<p></p>]]></description>
      <pubDate>Tue, 28 Oct 2014 18:39:00 +0000</pubDate>
      <dc:creator>Bilal</dc:creator>
    </item>
    <item>
      <title>nfomon</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1297</link>
      <description><![CDATA[<html><head>
</head><body><p>SUSv3: "The parameter name or symbol can be enclosed in braces, which
are optional except for positional parameters with more than one digit
or when parameter is followed by a character that could be interpreted
as part of the name."</p>
<p>That is, $10 is interpreted as $1 with a 0 afterwards. For positional
parameters after $9, you should refer to them as ${10} etc.</p>
<p>Some shells (e.g. dash) fail this conformance and actually allow $10
to mean ${10}.</p>
<p>I'm working on a new non-POSIX command shell that cannot have this
category of stupidity. Check it out: <a href="http://shok.io" rel="nofollow">http://shok.io</a> though note that this is EXTREMELY
early, i.e. I haven't even really launched yet, and any feedback is
appreciated.....</p>
<p></p>]]></description>
      <pubDate>Fri, 20 Dec 2013 07:32:00 +0000</pubDate>
      <dc:creator>nfomon</dc:creator>
    </item>
    <item>
      <title>Rakesh Sharma</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1296</link>
      <description><![CDATA[<html><head>
</head><body><p>I'd rewrite the last line as:</p>
<p>exec my_command ${1+"$@"};</p>
<p></p>]]></description>
      <pubDate>Mon, 20 May 2013 08:22:00 +0000</pubDate>
      <dc:creator>Rakesh Sharma</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1295</link>
      <description><![CDATA[<html><head>
</head><body><p>You know, I really should stay away from the shell. My mental
faculties responsible for things like ("$@") and "${ARGS[@]}" are
underdeveloped, so I'm just inflicting pain upon myself.</p>
<p></p>]]></description>
      <pubDate>Sat, 24 Mar 2012 00:21:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Aristotle Pagaltzis</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1294</link>
      <description><![CDATA[<html><head>
</head><body><p>Kartik Agaram:</p>
<p>I believe the suggestion to use zsh falls under Yossi’s “use another
language” clause. :-)</p>
<p></p>]]></description>
      <pubDate>Fri, 23 Mar 2012 19:09:00 +0000</pubDate>
      <dc:creator>Aristotle Pagaltzis</dc:creator>
    </item>
    <item>
      <title>Aristotle Pagaltzis</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1293</link>
      <description><![CDATA[<html><head>
</head><body><p>Sure /bin/sh is a real sh – but does that also mean /bin/bash is
absent? Because if you are worried only about Ubuntu, then the answer is
No. And if the answer is No then you can just put /bin/bash in your
shebang. (Just because Ubuntu makes you actually say that you want bash
and not just sh when you do want bash and not just sh does not mean you
cannot use bash at all.)</p>
<p>Then you can copy the args to an array variable using</p>
<p>local ARGS=( "$@" )</p>
<p>whose elements you can then molest to your heart’s desire. Once done,
you run your program with</p>
<p>exec foo "${ARGS[@]}"</p>
<p>Very simple.</p>
<p></p>]]></description>
      <pubDate>Fri, 23 Mar 2012 19:06:00 +0000</pubDate>
      <dc:creator>Aristotle Pagaltzis</dc:creator>
    </item>
    <item>
      <title>robohack</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1292</link>
      <description><![CDATA[<html><head>
</head><body><p>Here's a sample script I keep in my example sources for handy
use.</p>
<p>It shows how to squirrel away "$@" for safe keeping and re-use.</p>
<p>It could work with V7 sh, I think, by using expr instead of shell
arithmetic to increment the counter and of course by doing it inline
instead of defining a function (and also of course losing the "local"
declaration). One could probably do without expr too and just use $# and
shift to decrement it, but that would lead to the confusing result in
that the list_* variables would be numbered backwards.</p>
<p>A bit of trivia: with V7 sh, and probably most of its earlier
derivatives, one would have to use ${1+"$@"} instead of just "$@" in
order to avoid passing an empty parameter when none were originally
supplied. See:</p>
<p><a href="http://www.in-ulm.de/~mascheck/various/bourne_args/" rel="nofollow">http://www.in-ulm.de/~mascheck/various/bourne_args/</a></p>
<p>(AllanLane5: that was a joke right? You don't seriously think Perl is
more consistent than sh, do you? LOL! Robust? ROTFL! maybe a bit more
portable, but not since POSIX in, what, )</p>
<p>#! /bin/sh<br>
#<br>
# save_args — keep a list of quoted strings for later use via "$@"<br>
#<br>
# Note: creates a variable for each value, and uses these in
another<br>
# variable which can then be expanded with "eval" to re-reate the<br>
# original parameters, preserving words containing whitespace<br>
#<br>
# See also tshquote.sh for shell_quote() which can do the same,
but<br>
# produces its result on its stdout, and which does this simply
using<br>
# the normal single-quote characters.<br>
#<br>
# HOWEVER, shell_quote() requires printf(1) and sed(1), while this<br>
# variant does it all internally to the shell.<br>
#<br>
save_args()<br>
{<br>
local a c n<br>
c=0; n=$1; shift</p>
<p>for a in "$@"; do<br>
c=$(($c+1))<br>
eval $n="$$n \"\$${n}_$c\""<br>
eval ${n}_$c="$a"<br>
done<br>
}<br>
#<br>
# XXX Need to write free_args() to unset all the ${n}_$c
variables!!!<br>
#<br>
# use:<br>
#<br>
# save_args list -foo bar "arg with spaces" "don't panic"
'"Help!"'<br>
#<br>
# or:<br>
#<br>
# save_args list *.pdf # filenames with whitespace<br>
#<br>
# later:<br>
#<br>
# eval "gv ${list}"<br>
#<br>
# or, being a bit silly:<br>
#<br>
# . ./tshquote.sh<br>
#<br>
# eval set — ${list}<br>
#<br>
# for str in "$@"; do<br>
# q="$(shell_quote "$str")"<br>
# list2="${list2}${list2:+ }${q}"<br>
# done</p>
<p></p>]]></description>
      <pubDate>Wed, 14 Mar 2012 10:53:00 +0000</pubDate>
      <dc:creator>robohack</dc:creator>
    </item>
    <item>
      <title>AllanLane5</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1291</link>
      <description><![CDATA[<html><head>
</head><body><p>Not to be snarky, but isn't this why Perl was invented? Portable,
robust, and much more consistent than sh.</p>
<p></p>]]></description>
      <pubDate>Tue, 13 Mar 2012 09:23:00 +0000</pubDate>
      <dc:creator>AllanLane5</dc:creator>
    </item>
    <item>
      <title>Kartik Agaram</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1290</link>
      <description><![CDATA[<html><head>
</head><body><p>I'm surprised nobody's mentioned this, so I'll be that guy: use
zsh.</p>
<p>#!/usr/bin/env zsh</p>
<p></p>]]></description>
      <pubDate>Sun, 11 Mar 2012 01:50:00 +0000</pubDate>
      <dc:creator>Kartik Agaram</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1289</link>
      <description><![CDATA[<html><head>
</head><body><p>OK, so you've all convinced me that my knowledge of the shell is
insufficient for most practical purposes, and that I'd probably rather
keep it that way than delude myself into believing that I'd ever
improve... I'll try harder to use a language giving me an argument array
next time.</p>
<p>And, as to there being no $i beyond $9 – thanks, I'll mention
that...</p>
<p></p>]]></description>
      <pubDate>Sat, 10 Mar 2012 07:18:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Decklin Foster</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1288</link>
      <description><![CDATA[<html><head>
</head><body><p>In some simpler cases you can use shift and set to modify the
positional parameters. For example, to munge only the first one:</p>
<p>first="$1"; shift<br>
upcased="$(echo "$first" | tr a-z A-Z)"<br>
set — "$upcased" "$@"<br>
exec my_command "$@"</p>
<p>Unfortunately I don't think (off the top of my head) there's a way to
generalize this to unknown numbers of parameters.</p>
<p></p>]]></description>
      <pubDate>Fri, 09 Mar 2012 18:57:00 +0000</pubDate>
      <dc:creator>Decklin Foster</dc:creator>
    </item>
    <item>
      <title>Leandro Lucarella</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1287</link>
      <description><![CDATA[<html><head>
</head><body><p>About $(()), yes, you can do it in sh too, but you have to use the
regular parameter expansion syntax inside it: $(($nargs-1)). And is
POSIX, in case you wonder...<br>
<a href="http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_04" rel="nofollow">http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_04</a></p>
<p></p>]]></description>
      <pubDate>Fri, 09 Mar 2012 12:40:00 +0000</pubDate>
      <dc:creator>Leandro Lucarella</dc:creator>
    </item>
    <item>
      <title>saurabh</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1286</link>
      <description><![CDATA[<html><head>
</head><body><p>Your workaround breaks down anyway for non-bash sh if you have more
than 9 arguments.</p>
<p></p>]]></description>
      <pubDate>Fri, 09 Mar 2012 10:02:00 +0000</pubDate>
      <dc:creator>saurabh</dc:creator>
    </item>
    <item>
      <title>alenvers</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1285</link>
      <description><![CDATA[<html><head>
</head><body><p>One liner</p>
<p>args=`seq -s' ' -f '"$%1.0f"' 1 $#`</p>
<p></p>]]></description>
      <pubDate>Fri, 09 Mar 2012 09:37:00 +0000</pubDate>
      <dc:creator>alenvers</dc:creator>
    </item>
    <item>
      <title>Anton Kovalenko</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1284</link>
      <description><![CDATA[<html><head>
</head><body><p>I'd recommend relying on splicing and unsplicing (the latter may be
emulated, see below) as black boxes instead of tampering with single or
double quotes.</p>
<p>This one is pure sh (I hope it won't be messed up when posted):</p>
<p>#!/bin/sh</p>
<p>store() { r="$@"; }</p>
<p>r=<br>
for arg in "$@" ; do<br>
echo "Fiddling with $arg"<br>
store $r "$arg"<br>
done</p>
<p>echo "Args after fiddling: $r"</p>
<p>There once was a bug in an ancient sh, making "$@" expand incorrectly
into "" (one empty argument). That's why you can meet ${1+"$@"} in some
scripts, used instead of "$@", but I don't think you can stumble upon a
shell where it's still necessary.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 14:28:00 +0000</pubDate>
      <dc:creator>Anton Kovalenko</dc:creator>
    </item>
    <item>
      <title>Petr Viktorin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1283</link>
      <description><![CDATA[<html><head>
</head><body><p>And that is why shell sucks for anything over one line. It has lots
of nifty shortcuts that save your time, but they tend to get in the way
when you want robust scripts.<br>
For one-liners, though, it's perfect.</p>
<p>Your ending comment should come a little earlier – the general
solution for this should be to use a language where the arguments are in
a proper $container of strings. Only when that's not possible, invoke
black quote magic.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 13:09:00 +0000</pubDate>
      <dc:creator>Petr Viktorin</dc:creator>
    </item>
    <item>
      <title>Lance</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1282</link>
      <description><![CDATA[<html><head>
</head><body><p>I routinely do "sudo dpkg-reconfigure dash" on Ubuntu installations
to revert to bash, too much script breakage with the default "dash"
shell.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 12:56:00 +0000</pubDate>
      <dc:creator>Lance</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1281</link>
      <description><![CDATA[<html><head>
</head><body><p>updated the text to mention "$@" – thanks!</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 10:24:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1280</link>
      <description><![CDATA[<html><head>
</head><body><p>regarding the (()) syntax: yeah, but not in sh; Ubuntu's sh is a real
sh and not a bash, for some reason, which breaks loads of scripts used
to it being bash...</p>
<p>regarding "$@": it works if you don't need to fiddle with any of the
arguments, which my example doesn't do (the SO example I linked to
does.)</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 10:16:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Nathan</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1279</link>
      <description><![CDATA[<html><head>
</head><body><p>When performing basic arithmetic, at least in bash, you can do:
nargs=$((nargs-1)) which should be faster than expr.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 09:18:00 +0000</pubDate>
      <dc:creator>Nathan</dc:creator>
    </item>
    <item>
      <title>Daniel</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1278</link>
      <description><![CDATA[<html><head>
</head><body><p>See `man bash` in the section "Special Parameters". You want @, not
*, in the individually quoted form, like Barry mentioned.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 08:57:00 +0000</pubDate>
      <dc:creator>Daniel</dc:creator>
    </item>
    <item>
      <title>Barry Kelly</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/passing-shell-script-arguments-to-a-subprocess#comment-1277</link>
      <description><![CDATA[<p>Hm. I use:</p>
<p>exec my_command "$@"</p>
<p>which quotes it properly for you. For more complicated scenarios, I
use bash arrays and "${args[@]}" – it's not usually worthwhile avoiding
bash to get this all working portably.</p>
<p></p>]]></description>
      <pubDate>Thu, 08 Mar 2012 08:26:00 +0000</pubDate>
      <dc:creator>Barry Kelly</dc:creator>
    </item>
  </channel>
</rss>
