I would guess that you have /home/sawa/foo/bar/
on your path - i.e. a path with a trailing slash.
which
is iterating over each element of $PATH
and appending /argv[1]
and checking for the existence of that file. That causes a double-slash - one from the $PATH
part, and one from /argv[1]
.
A double-slash is no problem. It is collapsed to a single slash by the kernel. Only at the beginning of a path may a double-slash have special meaning, and not always then.
As for test
not working, ensure you are not using the shell built-in when calling test
. You usually do this by using a full path, but with bash you can also use enable -n test
to disable the built-in test
command.
Let's break this down into pieces.
This code runs the command :
with some arguments. The command :
does nothing and ignores its arguments. Therefore the whole command line does nothing, except whatever side effects happen in the arguments.
The syntax ${parameter_name:=value}
exists in all non-antique Bourne-style shells, including ash, bash, ksh and zsh. It sets the parameter to a default if necessary. It is equivalent to
if [ -z "$parameter_name" ]; then parameter_name=value; fi
… ${parameter_name}
In other words, if parameter_name
is not set or is set to an empty value, then set it to the indicated value; and then run the command, using the new parameter value. There is a variant, ${parameter_name=value}
, which leaves the parameter empty if it was empty, only using the indicated value if the parameter was unset.
You'll find this syntax documented under “parameter expansion” in the POSIX spec, and the dash, bash, ksh and zsh manuals.
There are variations on this syntax, in particular ${parameter_name:-value}
which let you use a default value for this expansion only, without assigning to the parameter.
In summary, : ${parameter_name:=value}
is a concise way of writing
if [ -z "$parameter_name" ]; then parameter_name=value; fi
Best Answer
In this case, it means ‘standard input’. It's used by some software (e.g.
tar
) when a file argument is required and you need to use stdin instead. It's not a shell construct and it depends on the program you're using. Check the manpage if in doubt!In this instance, standard input is the argument to the
-f
option. In cases where-
isn't supported, you can get away with using something liketar xvf /proc/self/fd/0
ortar xvf /dev/stdin
(the latter is widely supported in various unices).Don't rely on this to mean ‘standard input’ universally. Since it's not interpreted by the shell, every program is free to deal with it as it pleases. In some cases, it's standard output or something entirely different: on
su
it signifies ‘start a login shell’. In other cases, it's not interpreted at all. Muscle memory has made me create quite a few files named-
because some version of some program I was used to didn't understand the dash.