Bash Command Substitution
I am having a few problems with scripting a loop using command substitution, specifically with string expansion.
I want to run a query through a number of mysql hosts, but, I think, building the command as a string means that the arguments are presented as a single string rather than multiple strings Specifically: Code:
user=username What I want to know is how to correctly build commands as strings and then pass them on for command substitution in a shell script. I have tried all sort of combinations but to no avail. |
I looks like you have a few errors in the start of the script.
Code:
user=$username # maybe you want an argument instead as in "user=$1" and "pass=$2" for host in host1 host2 host3 host4; do ... done You assigned $password to $pass but used $password in the sql line. You can also build the entire command in a variable, let's call it mysqlcmd. Then a line like: ${mysqlcmd} will execute the cmd. |
The script was only an off the cuff example, I know it is not right, just trying to illustrate the bit I don't understand.
Quote:
Here is a complete example: Code:
for i in 1 2 |
eval does the trick:
Code:
#!/bin/bash Before the shell executes a command, it performs the following operations (check the manual for details): 1. Syntax analysis (Parsing) 2. Brace expansion 3. Tilde expansion 4. Parameter and variable expansion 5. Command substitution 6. Arithmetic expansion 7. Word splitting 8. Filename expansion 9. Quote removal It is important to realize that parsing takes place before parameter and command substitution. The result of a step n is subject to the next steps (n+), but the preceding steps (n-) are not re-executed. In other words: after for example variable expansion (step 4) the result is not re-parsed (step 1). In the example of the command: $cmd # cmd="date --date=\"1 days ago\""the command date --date=\"$i days ago\" is the result of variable expansion (step 4). Quote removal (step 9) removes the backslashes and turns the command into date --date="$i days ago". But since parsing (step 1) already has taken place, "1 days ago" is not seen as 1 argument but as 3 separate arguments: "1, days and ago", which gives you the error message: date: extra operand `ago"'To force one more run through the parsing/expansion procedure, use: eval $cmdNow first $cmd is expanded (steps 1-9) to date --date="1 days ago". Then eval causes the expanded string to be re-parsed again (steps 1-9), resulting in the correct command: date --date="1 days ago"Freddy Vulto http://fvue.nl/wiki/Bash |
Thank you very much.
An excellent answer that has significantly helped fill gaps in my understanding. |
Try this:
hosts="host1 host2 host3 host4" for h in $hosts |
All times are GMT -5. The time now is 01:25 AM. |