This question already has answers here:
Mathematical expression result assigned to a Bash variable
(3 answers)
How do I iterate over a range of numbers defined by variables in Bash?
(20 answers)
Closed 2 years ago.
This is my script:
#!/usr/bin/env bash
set -e
set -o errexit
set -o nounset
# set -o xtrace
input="${1:-}"
table="${2:-}"
length=$(jq length $input)
step=25
for i in {0..${length}..${step}}
do
low_index=$i * ${step}
high_index=$low_index + ${step} - 1
echo $low_index
echo $high_index
jq \
--arg table "$table" \
--arg low_index $low_index \
--arg high_index $high_index \
'{$table: [.[$low_index:$high_index] | {"PutRequest": {"Item": map_values({S: .})}}]}' \
csvjson.json > dynamo_${table}_${low_index}-${high_index}.json
done
This is the context of my directory:
$ ls
csvjson.json splitter.sh
Nevertheless, I'm getting:
$ bash ./splitter.sh csvjson.json socs
./splitter.sh: line 19: csvjson.json: command not found
Consider the line:
low_index=$i * ${step}
and assume that i=0 (which given the code in the question, it will not be, but that is clearly the intent) and step=5. When the shell parses that line, on the first round of word expansions it expands to:
low_index=0 * 5
There's no field splitting necessary, so round 2 is a no-op. The 3rd roundof expansion is pathname expansion, in which the * is expanded to all the names in the current directory, so the line expands to:
low_index=0 cvsjson.json splitter.sh 5
The shell tries to execute that line by looking for a file named cvsjson.json in PATH.
Related
This question already has answers here:
Syntax error in shell script with process substitution
(4 answers)
syntax error near unexpected token `<'
(2 answers)
Closed 2 years ago.
I want to parse the content of the HAProxy status socket so its less noisy. I wrote the following bash script:
#!/bin/sh
while IFS=, read -r pxname svname qcur qmax scur smax slim stot bin bout dreq dresp ereq econ eresp wretr wredis status weight act bck chkfail chkdown lastchg downtime qlimit pid iid sid throttle lbtot tracked type rate rate_lim rate_max check_status check_code check_duration hrsp_1xx hrsp_2xx hrsp_3xx hrsp_4xx hrsp_5xx hrsp_other hanafail req_rate req_rate_max req_tot cli_abrt srv_abrt comp_in comp_out comp_byp comp_rsp lastsess last_chk last_agt qtime ctime rtime ttime; do
[[ "$pxname" != "# pxname" ]] && echo "$pxname $svname $status"
done < <(echo "show stat" | socat stdio /var/run/haproxy.sock | sort)
When I execute it, I get the following error:
line 5: syntax error near unexpected token `<'
While I'm not a bash expert, my understanding of process substitution is that I can use it anywhere I normally can use a file. Indeed replacing <(....) with haproxy.csv works as expected. haproxy.csv in this case is the output of echo "show stat" | socat stdio /var/run/haproxy.sock | sort
How do I read the output of the commands within the parenthesis and process them in a loop?
a=HDH b=udud c=jsjsj bash secondscript
The command above works. I'd like to save the assignments in a variable, like so:
value="\
a=HDH \
b=udud \
c=ududj \
"
$value bash secondscript
But it gives an error:
test.sh: line 9: a=HDH: command not found
Why? What can I do instead?
bash's taking first item a=HDH as a command, what you need is :
value=(
"a=HDH"
"b=udud"
"c=ududj"
)
env "${value[#]}" bash secondscript
I define a function in Makefile
define write_file
for i in $( seq 1 10 )
do
echo "1234567" >> "tmp/test.txt"
done
endef
And
pre:
mkdir -p exe tmp
${call write_file}
But when I make pre,I got error:
mkdir -p exe tmp
for i in
/bin/sh: 1: Syntax error: end of file unexpected
Each line of a make-recipe is a single command that make runs in a single
new shell. So you need to make the body of the macro write_file into a single
shell command.
In addition, make expands anything of the unescaped form $(....),
treating .... as a defined or undefined make expression. So in your
case, make expands $( seq 1 10 ) to nothing. To stop make doing
that and let the shell expand $( seq 1 10 ), you need to escape $ for make,
which you do by writing $$ instead. The same goes for any $ in a make-recipe
that you intend to be expanded by the shell.
Putting these points together, you want:
define write_file
for i in $$( seq 1 10 ); \
do \
echo "1234567" >> "tmp/test.txt"; \
done
endef
This question already has answers here:
Bash - variable variables [duplicate]
(4 answers)
Dynamic variable names in Bash
(19 answers)
Closed 5 years ago.
From my code below, how to make the value of 'zz' become 500 after replacing 'critical_' with x on variable 'yy'
xab123=500
yy="critical_ab123"
zz=${"${yy//critical_/x}"}
echo $zz
instead the result, there is an error:
line 8: ${"${yy//critical_/x}"}: bad substitution
thanks
adi
May be like this:
xab123=500
yy="critical_ab123"
zz="${yy//critical_/x}"
echo ${!zz}
500
An interesting usage is when you call a bash function, you can use indirection on the parameters passed in. Then, you can nest calls to your indirection function in a nested manner using command substitution.
deref() { echo "${!1}"; }
aa="bb"
bb="cc"
cc="hello"
echo "$(deref aa)" # bb
echo "$(deref "$(deref aa)")" # cc
echo "$(deref "$(deref "$(deref aa)")")" # hello
Here's deref used to solve the OP's problem:
deref() { echo "${!1}"; }
xab123="500"
yy="critical_ab123"
zz="$(deref "${yy//critical_/x}")"
echo "$zz" # Outputs: 500
Applied edits based on #charles-duffy comments:
Disclaimer: reader beware, there are performance impacts to the command substitution used in this approach (FIFO creation, fork() of a subshell, read() and wait().
Quotes were added to protect against lossy expansion, i.e. echo "$zz" is better than echo $zz
Use POSIX-compliant function declaration syntax, i.e. replaced function deref { echo "${!1}" ; } with deref() { echo "${!1}" ; }
Corrected quoting issue for each quoting context
This question already has answers here:
Bash script returning "Not found" error
(2 answers)
Closed 9 years ago.
Hi i'm new to bash scripting but cannot understand why i get the command not found error when i try to assign to a local variable the result of this function call with parameters 20120920 5.
#!/bin/bash
function nDaysAgo () #date # daysago
{
date -d "${1} - ${2} days" +%Y%m%d;
}
so the script name is ndaysago, i'm first invoking the script with . ndaysago and then assigning the value like this:
newdate= nDaysAgo 20120910 5
it prints: 20120905: command not found
Meaning that the date execution is made but then tries to use the output as command, thats not what i would expect.
i have also tried assigning the new value to a variable within the function like so:
#!/bin/bash
function nDaysAgo () #date # daysago
{
var=$(date -d "${1} - ${2} days" +%Y%m%d)
}
but still nothing, mmmmmm
Spaces are not allowed around the = when assigning a variable. To invoke a function you should use the $(...) syntax which is called command substitution.
Change to:
newdate=$(nDaysAgo 20120910 5)