Home > Blockchain >  For loop with a command hold by a variable throws error
For loop with a command hold by a variable throws error

Time:10-27


BASE_DIR_APP_CONN="/opt/"

CMD_CONFIG_SNAPSHOT_DIR_APP_CONN="ls -ltrh $BASE_DIR_APP_CONN/local/ | awk '{print \$NF}' | tail -n  2 | xargs"

echo $CMD_CONFIG_SNAPSHOT_DIR_APP_CONN

for dir in $($CMD_CONFIG_SNAPSHOT_DIR_APP_CONN)
do
    echo "$dir"
done

Why this throws below error:

ls: cannot access |: No such file or directory
ls: cannot access awk: No such file or directory
ls: cannot access '{print: No such file or directory
ls: cannot access $NF}': No such file or directory
ls: cannot access |: No such file or directory
ls: cannot access tail: No such file or directory
ls: cannot access  2: No such file or directory
ls: cannot access |: No such file or directory
ls: cannot access xargs: No such file or directory
/opt/local/:
.....

When I run for loop with a command directly, it works as expected. Can someone please help? Thank you !

CodePudding user response:

Spliting a string into individual commands (i.e. breaking the pieces by |, ; and so on), is done before parameter expansion. Therefore,

foo | bar

runs foo and bar, connected by a pipe. However,

nonsense="foo | bar"
$nonsense

invokes the command foo with the two parameters | and bar. In order to run the pipe stored into the variable, I would have to write something like

eval "$nonsense"

but in general, this is a bad idea to do, not the least because you sooner or later will run into trouble with quoting and whitespace issues (as you would see if you tried this with your string).

In your case, I would use a function, for instance:

CMD_CONFIG_SNAPSHOT_DIR_APP_CONN() {
  ls -ltrh $BASE_DIR_APP_CONN/local/ | awk '{print \$NF}' | tail -n  2 | xargs
}

and calling it as

for dir in $(CMD_CONFIG_SNAPSHOT_DIR_APP_CONN)

Of course, this still suffers from several problems, such as parsing the output of ls and piping it into awk (this will break if the directory entries contain whitespace character), but this is not topic of your question, so I leave it like this.

  • Related