How to pass all arguments of a function along to another command?
Solution 1
Within your program
shell function, use "$@"
to refer to the list of all command line arguments given to the function. With the quotes, each command line argument given to program
would additionally be individually quoted (you generally want this).
program () {
"$GOBIN"/program "$@"
}
You would then call program
like so:
program -p hello_world -tSu
or, if you want to pass hello world
instead of hello_world
,
program -p 'hello world' -tSu
Using $1
refers to only the first command line argument (and $2
would refer to the second, etc.), as you have noticed. The value of $1
would additionally be split on white-spaces and each generated string would undergo filename globbing, since the expansion is unquoted. This would make it impossible to correctly pass an argument that contains spaces or filename globbing patterns to the function.
Solution 2
"$@"
is the way to provide pass all arguments received by a function / script, as answered by Kusalananda.
However, given that you seem to be using a folder with your go programs, I think you would be better served by simply adding your $GOBIN
folder to your PATH:
export GOPATH="$HOME/go_projects"
export GOBIN="$GOPATH/bin"
export PATH="$PATH:$GOBIN"
This way you could run any program stored in $GOBIN
just by typing its name (unless it has the same name of an existing program, we are appending $GOBIN to $PATH, so these programs would be picked last).
PS: For completeness, there is a third option which would be to use an alias instead of a function, you could place in .bashrc
:
alias program="$GOBIN/program"
Related videos on Youtube
nooby
Updated on September 18, 2022Comments
-
nooby over 1 year
Hello I have this in my
~/.bash_profile
export GOPATH="$HOME/go_projects" export GOBIN="$GOPATH/bin" program(){ $GOBIN/program $1 }
so I'm able to do
program "-p hello_world -tSu"
. Is there any way to run the program and custom flags without using the quotation marks? if I do justprogram -p hello_world -tSu
it'll only use the-p
flag and everything after the space will be ignored.-
Zorawar over 3 years"...is there anyway to run the program and custom flags without using the quotation marks?" Yeah, install zsh! The reason why you should have quotes in bash and in some other shells is for historical reasons, which you can look up. Basically, bash will "split" variables whenever they are not quoted. Consider the following code:
foo() { echo "1: $1"; echo "2: $2"; }; var="a b"; foo $var
, whereby bash "splits" the string invar
into two arguments tofoo
(namely, "a" and "b"). (Zsh does away with this legacy behaviour, so quotes are rarely needed.) -
ilkkachu over 3 years@Zorawar, and how would Zsh and the fact that it does not split help here? If you did
foo() { ls $1; }
andfoo "-l foo.txt"
in Zsh, it wouldn't work exactly because of the lack of splitting, andfoo -l foo.txt
also wouldn't pass all the arguments along. Regardless of the shell, you still need$@
to pass all the arguments. -
Zorawar over 3 years@ilkkachu OP: "Is there any way to run the program and custom flags without using the quotation marks." My tongue-in-cheek answer was essentially, no, not unless you use a shell that does this. The reason why bash does not do this is because of word splitting, which I thought the OP would like to know in order to appreciate why this is so. Yes, zsh does not split on raw strings, but we are talking about the behaviour of parameters, not strings. I don't see why
$@
joined the discussion, though. -
ilkkachu over 3 years@Zorawar, the example was
program "-p hello_world -tSu"
, which, when used with$GOBIN/program $1
runs$GOBIN/program -p hello_world -tSu
, that is,$GOBIN/program
gets three distinct arguments. To do the same without quotes, they'd doprogram -p hello_world -tSu
, where the functionprogram
itself gets three arguments.$1
only contains one of them, in both Bash and Zsh. To pass all the arguments on, you have to use$@
. (Or if you want to lock yourself to exactly three arguments,$1
to$3
.) With Zsh you could use just$@
, but with Bash, you need to quote it"$@"
. -
Zorawar over 3 years@ilkkachu I appreciate that, but I am not, and did not, address that. The answers below have covered that sufficiently well. I just added my comment as supplementary information about why quotes in general are very much recommended in bash, which was my reading between the lines of why the OP asked about quotation marks since, on the surface, why doesn't
$1
include all the other arguments shows a certain lack of understanding of how and why quotes are needed in shell code. -
ilkkachu over 3 years@Zorawar, I fail to see how
$1
not including anything but the first argument has anything to do with quotes. Yes of coursefoo $var
will split in Bash but not Zsh, but that's not what they were doing in the question. Yes, perhaps the issue here was that they didn't know what$1
is, or how to refer to the other arguments, but your comment did nothing to help that either. Really, I just hope people would write comments like that as answers so that they could be downvoted.
-
-
nooby over 3 yearsThanks this worked, though I don't know why you need quotations for the $GOBIN, confuses me a bit. but thats okay tyvm! will accept when I am able too
-
Kusalananda over 3 years@nooby In this particular case, you may not need quoting of
$GOBIN
, but you would definitely need it if it happened to contain spaces. See unix.stackexchange.com/questions/131766 and unix.stackexchange.com/questions/68694 In general, it's safest to always quote variable expansions, unless you know for sure that you don't need to (or you want to actually invoke splitting and globbing on the value of the variable). -
nooby over 3 yearsThanks for adding an even more in depth expiation and answering my second question, much appreciated. i'll check those threads out, have a good day