#!/bin/csh
set passFail_file = "name"
set numErrs = `/bin/grep -c ERROR $passFail_file`
echo "numErrs is $numErrs" # displays numErrs is 0, which isn't always correct
set dirLocale = `/bin/sed q $passFail_file` #capture line 1 in file, which is nonBlank
echo "dirLocale is $dirLocale" # displays: dirLocale is
When I run the above script, I can not get dirLocale to assign. Is there an equivalent of eval in csh? What would be the syntax? I'm thinking I'm missing out on the mix of backquotes, and order of operations.
System was acting strangely. All is well, using the above syntax. Question closed. Thank you.
Related
This question already has answers here:
Dynamic variable names in Bash
(19 answers)
Closed 6 years ago.
I want to declare a variable, the name of which comes from the value of another variable, and I wrote the following piece of code:
a="bbb"
$a="ccc"
but it didn't work. What's the right way to get this job done?
eval is used for this, but if you do it naively, there are going to be nasty escaping issues. This sort of thing is generally safe:
name_of_variable=abc
eval $name_of_variable="simpleword" # abc set to simpleword
This breaks:
eval $name_of_variable="word splitting occurs"
The fix:
eval $name_of_variable="\"word splitting occurs\"" # not anymore
The ultimate fix: put the text you want to assign into a variable. Let's call it safevariable. Then you can do this:
eval $name_of_variable=\$safevariable # note escaped dollar sign
Escaping the dollar sign solves all escape issues. The dollar sign survives verbatim into the eval function, which will effectively perform this:
eval 'abc=$safevariable' # dollar sign now comes to life inside eval!
And of course this assignment is immune to everything. safevariable can contain *, spaces, $, etc. (The caveat being that we're assuming name_of_variable contains nothing but a valid variable name, and one we are free to use: not something special.)
You can use declare and !, like this:
John="nice guy"
programmer=John
echo ${!programmer} # echos nice guy
Second example:
programmer=Ines
declare $programmer="nice gal"
echo $Ines # echos nice gal
This might work for you:
foo=bar
declare $foo=baz
echo $bar
baz
or this:
foo=bar
read $foo <<<"baz"
echo $bar
baz
You could make use of eval for this.
Example:
$ a="bbb"
$ eval $a="ccc"
$ echo $bbb
ccc
Hope this helps!
If you want to get the value of the variable instead of setting it you can do this
var_name1="var_name2"
var_name2=value_you_want
eval temp_var=\$$var_name1
echo "$temp_var"
You can read about it here indirect references.
You can assign a value to a variable using simple assignment using a value from another variable like so:
#!/usr/bin/bash
#variable one
a="one"
echo "Variable a is $a"
#variable two with a's variable
b="$a"
echo "Variable b is $b"
#change a
a="two"
echo "Variable a is $a"
echo "Variable b is $b"
The output of that is this:
Variable a is one
Variable b is one
Variable a is two
Variable b is one
So just be sure to assign it like this b="$a" and you should be good.
I have a C program that I want to run without having to manually type commands into. I have 4 commands (5 if you count the one to exit the program) that I want given to the program and I don't know where to start. I have seen some stuff like
./a.out <<<'name'
to pass in a single string but that doesn't quite work for me.
Other issues I have that make this more difficult are that one of the commands will give an output and that output needs to be a part of a later command. If I had access to the source code I could just brute force in some loops and counters so I am trying to get a hold of it but for now I am stuck working without it. I was thinking there was a way to do this with bash scripts but I don't know what that would be.
In simple cases, bash script is a possibility: run the executable in coproc (requires version 4). A short example:
#!/bin/bash
coproc ./parrot
echo aaa >&${COPROC[1]}
read result <&${COPROC[0]}
echo $result
echo exit >&${COPROC[1]}
with parrot (a test executable):
#!/bin/bash
while [ true ]; do
read var
if [ "$var" = "exit" ]; then exit 0; fi
echo $var
done
For a more serious scenarios, use expect.
I try to transfer the excellent example docker-haproxy from centos to alpine.
A shell script is used to process a list of values given as parameters to the script into an array, then write these values plus their index to some file.
The following construction works in bash:
ServerArray=${SERVERS:=$1}
...
for i in ${ServerArray[#]}
do
echo " " server SERVER_$COUNT $i >> /haproxy/haproxy.cfg
let "COUNT += 1"
done
but not in ash (or sh):
syntax error: bad substitution
The error refers to line
for i in ${ServerArray[#]}
What is the correct syntax here? I guess the line
ServerArray=${SERVERS:=$1}
does not define an array as intended, but googling for long did not help me.
bash to sh (ash) spoofing says
sh apparently has no arrays.
If so, how to solve the problem then?
I guess I can do with this construction:
#!/bin/sh
# test.sh
while [ $# -gt 0 ]
do
echo $1
shift
done
delivers
/ # ./test 172.17.0.2:3306 172.17.0.3:3306
172.17.0.2:3306
172.17.0.3:3306
which is what I need to proceed
I am writing a simple makefile named run.mk, as shown in the following code.
a = 0
b := $(shell echo `expr $(a) + 1`)
app: main.o
gcc -o app main.o
main.o: main.c
gcc -c main.c
test:
while [ $(a) -lt 10 ];\
do\
echo $(a);\
a:= $(shell echo `expr $(a) + 1`);\
echo $(a);\
done
when i run this makefile using command make -f run.mk test, error comes: a not found and loop runs infinitly i.e value of variable a is not updated at a:= $(shell echo expr $(a) + 1) within while loop. However at the beginning, value of variable b is set to 1 via the same code line $(shell echo expr $(a) + 1). Someone please tell how to update the value of variable a within the loop.
Thank you.
You're mixing up make syntax and shell syntax. Commands that are in a recipe are run by the shell (after make expands them one time). The shell is a separate process and anything that happens in the shell is completely invisible to make. All make sees is the exit code (to know if there was an error or not). It is not possible for the shell to modify the behavior of make in any way (change variable values, etc.)
So with your rule what make does is first expand the recipe for test (by the way, this is a very bad name for a target because test is actually a real program already on your system), to get this result:
while [ 0 -lt 10 ]; \
do \
echo 0; \
a:= 1; \
echo 0;\
done
After that expansion is complete it sends that text to the shell to execute, and obviously that will run forever (as well, note that a:= 1 is not a valid shell command).
Since you only told us what you tried but didn't tell us what you actually wanted to do in the first place, we can't help you do what you want to do.
If what you want to do is write a recipe that will loop 10 times printing a value, you have to do it entirely using shell syntax, NOT make syntax. Like this:
test:
a=$(a); \
while [ $$a -lt 10 ];\
do\
echo $$a;\
a=`expr $$a + 1`;\
echo $$a;\
done
The $$ escapes variables from being expanded by make, and results in this shell script being run by the shell:
a=0; \
while [ $a -lt 10 ];\
do\
echo $a;\
a=`expr $a + 1`;\
echo $a;\
done
You're mixing shell script variables and make variables.
The recipe for test is a shell script (from while to done). Make variables, such as $(a) are expanded before it starts to execute, so the while line is while [ 0 -lt 10 ] which is always true.
The assignment a:=... doesn't work, because it's makefile syntax, not shell syntax. Even if it did work, it wouldn't affect the while line.
The script I'm writing will require me to pass some command line parameters. I would like to use these parameters within an array, but I'm not sure how.
A very basic example of this would be (script run as ./script.sh array1):
#!/bin/bash
array1=( a b c d )
echo ${#$1[#]}
The output should be 4, but I receive the following error:
line 5: ${#$1[#]}: bad substitution.
I don't have to use arrays, but would like to.
Thanks for any ideas
you need to get bash to substitute the value of $1 before evaluating the line, try this...
eval echo \${#$1[#]}
eval echo '${#'$1'[#]};'