Bash for loop with spaces

I would like to do something like this:

COMMANDS='"ls /" "df ~" "du -hs ~/Devel/"' for i in $COMMANDS; do echo $i done 

Where is the result:

 ls / df ~ du -hs ~/Devel/ 

But I can not find the correct syntax for spaces.

+5
source share
2 answers
 COMMANDS=("ls /" "df ~" "du -hs ~/Devel/") for i in "${COMMANDS[@]}"; do echo "$i" done 

It uses an array to store commands. This function is also available in ksh , zsh , but not in sh .

Arrays behave like an array of arguments $@ . Applying a for loop to "${ARRAY_NAME[@]}" (quotation marks are important) will give you every element in a row. If you omit the quotation marks, they will all be smoothed and split by the delimiters present in your IFS environment variable ( '\t' , '\n' and ' ' by default).

+8
source

I would recommend you not to do this at all. Firstly, it is much longer and more difficult than just writing.

 ls / df ~ du -hs ~/Devel/ 

Secondly, flat lines cannot store delimited nested lines. There is no way (and yes, I ignore eval ) to distinguish between spaces that separate commands and spaces that separate arguments within a command. You can use an array for simple commands, but you cannot embed arrays, so as soon as the arguments of one of your commands contain spaces, you return to the original problem.

 commands=("ls /" "df ~" "du -hs ~/Devel") # OK, but... commands=("ls \"foo bar\"" "echo 'hello world'") # No. 

If you want your script to be able to execute arbitrary user-defined commands, instead, have the source files from a well-known directory (i.e. implement a plug-in system).

 command_dir=~/myscript_plugins for f in "$command_dir"; do source "$f" done 

where $command_dir contains one file for each of the commands you want to run.

Or, define a series of functions and save their names in a string (function names cannot contain spaces, so there is no need for arrays):

 lister () { ls /; } dfer () { df ~; } duer () { du -hs ~/Devel; } commands="lister dfer duer" for command in $commands; do $command done 

or

 commands=(lister dfer duer) for command in "${commands[@]}"; do $command done 

Next: I'm trying to add a command to a variable, but complex cases always fail!

+5
source

Source: https://habr.com/ru/post/1232280/


All Articles