LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   shell quoting within a function (https://www.linuxquestions.org/questions/linux-software-2/shell-quoting-within-a-function-581549/)

dazdaz 09-01-2007 07:00 PM

shell quoting within a function
 
Hi all,

So here's a nice brain teaser. I am trying to write a shell function that will allow me to view files in directories with spaces or special characters. I am using eval to pad this out.

It works fine with a shell alias, but not a shell function.

I've tried so many variations, I need some guidance. Please help :-)

$ mkdir abc\ xyz

$ set -xv
$ alias ll='ls -l `eval $@`'
alias ll='ls -l `eval $@`'
+ alias 'll=ls -l `eval $@`'
history -a
++ history -a
$ ll abc\ xyz/
ll abc\ xyz/
eval $@
++ eval
+ ls -l 'abc xyz/'
total 0
-rw-r--r-- 1 root root 0 2007-09-02 00:53 testfile
history -a
++ history -a



$ function lll () { ls -l `eval $@`; }
function lll () { ls -l `eval $@`; }
history -a
++ history -a

$ lll abc\ xyz/
lll abc\ xyz/
+ lll 'abc xyz/'
eval $@
++ eval abc xyz/
abc xyz/
+++ abc xyz/
bash: abc: command not found
+ ls -l
total 4944
-rw-r--r-- 1 root root 3837738 2007-04-10 23:36 allpackages.html
-rw-r--r-- 1 root root 1036131 2007-04-10 21:04 debian4.0-r0-etch-dvd1
-rw-r--r-- 1 root root 90937 2007-06-23 22:08 report_all_plugins.html
history -a
++ history -a

unSpawn 09-02-2007 02:56 AM

Why would you want to "read ARGs as input to the shell and execute the resulting command" (aka 'eval') things when you use a default IFS and have already escaped space?

colucix 09-02-2007 03:00 AM

Quote:

Originally Posted by dazdaz (Post 2878166)
It works fine with a shell alias, but not a shell function.

Hi. I'd tell the opposite. What you expected is done by the function not by the alias: it is the logic not quite correct. Using eval means execute its arguments as a command. If you do something like
Code:

eval somefile somedir
the shell tries to execute the command
Code:

somefile somedir
that is obviously not correct. Regarding the alias and the function, in case of the alias you obtain
Code:

$ ll abc\ xyz/
ll abc\ xyz/
eval $@
++ eval
+ ls -l 'abc xyz/'

Here eval evaluates nothing, because $@ are the arguments (better, the positional parameters) to the ls -l command, not to the eval subprocess. Evaluating a null string means to execute nothing, therefore no error is given. On the contrary in the function you obtain
Code:

$ lll abc\ xyz/
lll abc\ xyz/
+ lll 'abc xyz/'
eval $@
++ eval abc xyz/
abc xyz/
+++ abc xyz/
bash: abc: command not found
+ ls -l

Here the positional parameters are the arguments to the function and they are evaluated in any position (statement) inside the function itself. The eval command (in blue) evaluates the string "abc xyz" and try to execute it as a command, therefore the "command not found error". Then ls -l (in dark red) is executed with no arguments at all, because of the previous error.

dazdaz 09-02-2007 04:15 AM

It makes more sense now.

function lll () { ls -l "$@"; }

Thanks.

archtoad6 09-03-2007 11:01 AM

The key is quoting the $@, this causes the positional parameters (arguments) to seen as the separate words they were in the command line.

See man bash & do a search for 'Special Parameters'.


All times are GMT -5. The time now is 10:42 AM.