I need some help in Bash function while passing arguments. I need to pass arguments into SQL query in Bash but I am getting error message.
#!/bin/bash --
whw='mysql -uroot -proot -habczx.net'
function foo() {
for v in "$#"; do
eval "$v"; # line 9
echo "${v}";
done
${whw} -e"select id, idCfg, idMfg, $DATE from tblMfg"
}
foo DATE="curdate()"
Below is the error message I get:
$ sh test4.sh
test4.sh: eval: line 9: syntax error near unexpected token `('
test4.sh: eval: line 9: `DATE=curdate()'
test4.sh: line 9: warning: syntax errors in . or eval will cause future versions of the shell to abort as Posix requires
DATE=curdate()
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from tblMfg limit 4' at line 1
==
If I change in function call to below I do not get any error message:
foo DATE="2014-12-21"
==
Any help?
Thanks!
The problem is the evaluated expression. You can see that by typing it:
$ DATE=bla()
-bash: syntax error near unexpected token `('
If you put it in quotes, it will work:
$ DATE="bla()"
In order to pass the quotes to the eval, they need to be protected from evaluation at callsite:
foo 'DATE="curdate()"'
should do the trick.
BTW: this is rather dangerous to eval a string, especially if the arguments are from untrusted users, one could use foo "rm -rf /" :)
I am not sure why you need the eval, instead of $DATE you could also use $1 and then
${whw} -e"SELECT ... $1...."
foo "curdate()"
Related
I have a shell script that consist of two files, one bash-file (main.sh) and one file holding all my config-variables(vars.config).
vars.config
domains=("something.com" "else.something.com")
something_com_key="key-to-something"
else_something_com_key="key-to-something else"
In my code i want to loop through the domains array and get the key for the domain.
#!/usr/bin/env sh
source ./vars.config
key="_key"
for i in ${domains[#]};
do
base="$(echo $i | tr . _)" # this swaps out . to _ to match the vars
let farmid=$base$key
echo $farmid
done
So when i run it i get an error message
./main.sh: line 13: let: key-to-something: syntax error: operand
expected (error token is "key-to-something")
So it actually swaps it out, but i cant save it to a variable.
You can expand a variable to the value of its value using ${!var_name}, for example in your code you can do:
key="_key"
for i in ${domains[#]};
do
base="$(echo $i | tr . _)" # this swaps out . to _ to match the vars
farmid=$base$key
farmvalue=${!farmid}
echo $farmvalue
done
I have a very large script, and I'm trying to introduce a for loop.
To test that I have the right syntax, at line 120 say, I have:
for M in "1 2 3 4"; do
echo $M
end
However I get the error:
./script.sh: line 120: syntax error: unexpected end of file
Even more worryingly, I get the same if I run:
for M in $( ls ); do
echo $M
end
What am I doing wrong here?
You need to use done not end to finish a for loop
I have a problem with the done.
It says I have some typo error but I can't figure what's wrong at all.
Here is the code:
#./bin/bash
until [$err == 0];
do
java -Xms512m -Xmx512m -cp lib/*:lib/uMad/*:mysql-connector-java-5.1.15-bin.jar:l2jfrozen-core.jar com.l2jfrozen.gameserver.GameServer
err=$?
sleep 5
done
Your shebang line is wrong. #./bin/bash will not execute bash.
It should read #!/bin/bash. You are probably using a shell other than bash to invoke this script.
Also, beware that the [$err == 0] line expands the value of $err, which is probably an empty string, unless it has been exported. If it's empty, this will result in an error, because Bash will be interpreting [ == 0].
The safest approach is this:
unset err
until [ "$err" == "0" ];
do
# etc...
done
From my experience when working with brackets and if loops, you need proper spacing and double, not single brackets. There needs to be space on each side of the double brackets with the exception of the semi-colon. Here is an example block:
#!/bin/bash
err=5
until [[ $err == 0 ]]; do
((err-=1));
echo -e "$err\n";
sleep 3
done
I do not see why the same would not apply to a do until loop.
You're probably aware but your heading has a period in it instead of a shebang.
#./bin/bash
I wrote simple script as follow
#!/bin/bash
auth_type=""
SM_Read-only="Yes"
SM_write-only="No"
echo -e ${SM_Read-only}
echo -e ${SM_Write-only}
if [ "${SM_Read-only}" == "Yes" ] && [ "${SM_Write-only}" == "Yes" ]
then
auth_type="Read Write"
else
auth_type="Read"
fi
echo -e $auth_type
And when i execute it i got following output with errors.
./script.bash: line 5: SM_Read-only=Yes: command not found
./script.bash: line 6: SM_write-only=No: command not found
only
only
Read
Any one know correct way to declare the variable with "-" (dash)?
EDIT:
have getting response from c code and evaluate the variables for example
RESP=`getValue SM_ Read-only ,Write-only 2>${ERR_DEV}`
RC=$?
eval "$RESP"
from above scripts code my c binary getValue know that script want Read-only and Write-only and return value to script.So during eval $RESP in cause error and in my script i access variable by
echo -e ${SM_Read-only}
echo -e ${SM_Write-only}
which also cause error.
Rename the variable name as follows:
SM_Read_only="Yes"
SM_write_only="No"
Please, don't use - minus sign in variable names in bash, please refer to the answer, on how to set the proper variable name in bash.
However if you generate the code, based on others output, you can simply process their output with sed:
RESP=$(getValue SM_ Read-rule,Write-rule 2>${ERR_DEV}|sed "s/-/_/g")
RC=$?
eval "$RESP"
- is not allowed in shell variable names. Only letters, numbers, and underscore, and the first character must be a letter or underscore.
I think you cant have a dash in your variables names, only letters, digits and "_"
Try:
SM_Read_only
Or
SM_ReadOnly
This is my function where I'm reading a file, splitting each line by space and creating an array. I want to use 1st and 2nd element from the array as key and value to an associative array. The 1st element is an ip address.
function testRead {
NEWHOST_IPS_OUT=<my_file>
declare -a HOSTS_IP_ARR
while read line
do
if [[ -z "$line" ]] || [[ "$line" =~ "#" ]]; then
continue
fi
STR_ARRAY=($line)
HOST_IP=${STR_ARRAY[1]}
HOST_AZ=${STR_ARRAY[2]}
HOSTS_IP_ARR["$HOST_IP"]="${HOST_AZ}"
HOSTS_IP_ARR[hello]=2
done < "$NEWHOST_IPS_OUT"
}
Issues & Findings:
* declare -A doesn't work, using `GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)`
./test.sh: line 4: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
* I tested with constant values using '-a' for an associative array. It worked
* On running this script I get the following error:
./test.sh: line 14: 127.0.0.1: syntax error: invalid arithmetic operator (error token is ".0.0.1")
This is line 14: HOSTS_IP_ARR["$HOST_IP"]="${HOST_AZ}"
declare -A doesn't work, using `GNU bash, version **3.2.25(1)-release** (x86_64-redhat-linux-gnu)`
There's your problem. Associative arrays were only introduced into bash in version 4.
declare -a creates a regular, non-associative array.
It could appear to be associative:
declare -a arr
arr["somekey"]=42
echo "${arr["somekey"]}" # gives 42
but
arr["someotherkey"]=1000
echo "${arr["somekey"]}" # now gives 1000
This is because "somekey" and "someotherkey" are interpretted as arithmetic expressions. Bash tries to look them up as variable names, find them unset, and therefore consider the value to be 0.
127.0.0.1 is an invalid arithmetic expression, and that's why you get that error.