8

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
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
RR_
  • 111
  • 1
  • 1
  • 5

4 Answers4

15

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
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
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.

John1024
  • 73,527
  • 11
  • 167
  • 163
1
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"
mikeserv
  • 57,448
  • 9
  • 113
  • 229
-1

variable = command

backquote character(`)

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