user619271
user619271

Reputation: 5022

Why does "basename <(readlink -f filename)" return "63", not the actual basename?

Is it possible to use basename and readlink in a one line? Something like:

ln -s /usr/local/src symlink
echo `basename <(readlink -f "./symlink")`

except that script above prints 63 instead of src.

Upvotes: 2

Views: 795

Answers (1)

randomir
randomir

Reputation: 18697

Use the command substitution instead of the process substitution:

echo "$(basename "$(readlink -f "./symlink")")"

or, if that's your complete line, echo is redundant:

basename "$(readlink -f "./symlink")"

Multiple $(..) command substitutions can be nested without any escaping or quoting needed (unlike with the old-style backquote version). Also note that if the substitution appears within double quotes, word splitting and filename expansion are not performed on the results.

To clarify the difference: when you say <(cmd), the cmd is executed and the result is made available in a file, handle to which is returned, something like /dev/fd/63. Since the basename acts on a filename given, not its contents, it returns 63.

Unlike process substitution, the $(cmd) will execute the cmd and return the result of command (its standard output). You can then store it in a variable, like res=$(cmd), or reuse it in-place, like cmd "$(cmd)".

Upvotes: 6

Related Questions