Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shell tilde expansion does not work when passed as an option

I find tilde expansion does not work for the following situation:

$ set -x

$ ./print_arg.pl destdir=~/test
+ ./print_arg.pl 'destdir=/root/test'
destdir=/root/test

$ ./print_arg.pl dest-dir=~/test
+ ./print_arg.pl 'dest-dir=~/test'
dest-dir=~/test

$ ./print_arg.pl -destdir=~/test
+ ./print_arg.pl '-destdir=~/test'
dest-dir=~/test

The contents of print_arg.pl is

#!/usr/bin/perl
print $ARGV[0],"\n";

According to Order of Shell processing, Shell will split word before "tilde expansion". And I noticed that word split are different actually. What is the reason for the different results?

like image 310
lisper Avatar asked Oct 04 '22 16:10

lisper


1 Answers

Tilde expansion also occurs in shell variable assignment, which destdir=~/test resembles. dest-dir=~/test and -destdir=~/test do not, since - is not a valid character in a variable name. Although the shell is not evaluating destdir=~/test as a variable assignment (it would, if set -k is used), it appears the parser is still treating it as such and performing tilde expansion on the RHS.

From http://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html#Tilde-Expansion:

Each variable assignment is checked for unquoted tilde-prefixes immediately following a ‘:’ or the first ‘=’. In these cases, tilde expansion is also performed. Consequently, one may use file names with tildes in assignments to PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.

Note that with the -k option set, proper variable assignments are processed as such and removed from the argument list passed to print_arg.pl:

~ $ set -kx
~ $ ./print_arg.pl destdir=~/bin foo
+ destdir=/Users/clint/bin
+ ./print_arg.pl foo
foo
~ $ ./print_arg.pl dest-dir=~/bin foo
+ ./print_arg.pl 'dest-dir=~/bin' foo
dest-dir=~/bin
like image 90
chepner Avatar answered Nov 20 '22 18:11

chepner