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
RR_
  • 111

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
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
  • 74,655
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
  • 58,310
-1

variable = command

backquote character(`)

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