7

I assign command ls to my variable my_File but when I run it as $my_File it does not work. Can you please explain why?

#!/bin/bash
my_File='ls -f | grep -v '\/''
$my_File
6
  • Try my_File=$(ls -f | grep -v '\/') or substitute the outer quotes by backquotes... – user62916 Mar 25 '14 at 18:29
  • 1
    Why not use alias? – mkc Mar 25 '14 at 18:33
  • Seconding @Ketan's question, what is your motivation for wanting to do this? – John1024 Mar 25 '14 at 18:35
  • What kind of quoting is 'ls -f | grep -v '\/'' supposed to be? – Hauke Laging Mar 25 '14 at 18:45
  • it has to list only files in $PWD – RR_ Mar 25 '14 at 19:00
12

The line you wrote defines a variable whose value is the string ls -f | grep -v /. When you use it unquoted, it expands to a list of words (the string is split at whitespace): ls, -f, |, grep, -v, /. The | character isn't special since the shell is splitting the string, not parsing it, so it becomes the second argument to the ls command.

You can't stuff a command into a string like this. To define a short name for a command, use an alias (if the command is complete) or a function (if the command has parameters and is anything more than passing some default arguments to a single command). In your case, an alias will do.

alias my_File='ls -f | grep -v /'
my_File
2
$ my_File='ls -f | grep -v '\/''
$ $my_File 
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
[snip]

When interpreting $my_File, bash treats the characters in it as just characters. Thus, for one, the command line has a literal | character in it, not a pipe.

If you are trying to execute $my_File on the command line and have the pipes work, you need eval $my_File.

0
echo "${var='ls -f | grep -v "\/"'}" |sh

You certainly need an interpreter - though not necessarily eval.

. <<-HEREDOC /dev/stdin
    $var
HEREDOC

echo "$var" | . /dev/stdin

There are a lot of ways to get there.

${0#-} -c "$var"

sh - c "$var"
-1

variable = command

backquote character(`)

so like var = pwd echo $var = /home/user/foo

1
  • 2
    That would assign the output of the command to the variable which is not what is being asked for here. – Stéphane Chazelas Jan 20 '17 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.