Inserting to an shell array in a loop [duplicate] - shell

This question already has answers here:
A variable modified inside a while loop is not remembered
(8 answers)
Closed 2 years ago.
I am trying to insert values in to an array in a loop as follows:
branches_to_delete=()
cat branches.txt | while read branch_name
do
BRANCH_COUNT=$(git ls-remote | grep -w $branch_name | wc -l)
if [ $BRANCH_COUNT -eq 0 ]; then
echo "Branch does not exist"
branches_to_delete+=($branch_name)
elif [ $BRANCH_COUNT -eq 1 ]; then
echo "Branch exists"
else
echo "Not valid result"
fi
done
echo "Loop finished"
echo ${branches_to_delete[#]}
But when I printout branches_to_delete it is actually empty.
What am I doing wrong here?

With the pipe from cat branches.txt into the read loop, you create a subshell that cannot access the parent shell's branches_to_delete array.
You can fix this by avoiding the pipe and saving a useless use of cat:
branches_to_delete=()
while read branch_name; do
...
done < branches.txt
(Make sure nothing in ... reads from read's stdin. You'll notice if something is missing).

Related

`echo` is stripping newlines in Bash script [duplicate]

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
When should I double-quote a parameter expansion? [duplicate]
(1 answer)
Closed 5 months ago.
If I have a file containing newlines, the below script will output the file as is, with newlines:
#!/bin/bash
FOO=$(cat filename.yaml)
echo "$FOO"
but
#!/bin/bash
FOO=$(cat filename.yaml)
FOO=$(echo $FOO)
echo "$FOO"
outputs the file all on one line. How come?
I do not recommend storing the contents of entire files in a single variable. In my experience that can have unpredictable results.
/usr/bin/env bash -x
index=$(wc -l filename.yaml | cut -d' ' -f1)
count=1
next () {
[[ "${count}" -lt "${index}" ]] && main
[[ "${count}" -eq "${index}" ]] && exit 0
}
main () {
line=$(sed -n "${count}p" filename.yaml)
echo "var${count}=${line}" >> varfile
count=$(($count+1))
next
}
next
If you source varfile at the start of another script, it will give you every line from that file, in its' own variable.

bash setting variable getting error command not found [duplicate]

This question already has answers here:
Indirect variable assignment in bash
(7 answers)
Closed 9 months ago.
I'm writing one small bash script for my Project
but i getting some errors
#!/bin/bash
count=$(cat Downloads/datei.csv | wc -l);
for((i=115;i<="122";i++)); do
line$i=$(sed -n $i"p" Downloads/datei.csv);
echo "line$i";
done
i trying to get every line from CSV in some variable
The erroĊ•
count.sh: line 4: line115=: command not found
if [[ -z "line$i" ]];
then
echo "$i is empty";
else
echo "$i is NOT empty";
fi
the second code gives me the same error
Suggest compose the code together, just update line$i to a temporary normal variable without other var like line_get.
One more thing, you need to update -z "line$i" to -z "$line_get". As in bash, you should use $ and the var name to get the value.
Looks like:
#!/bin/bash
count=$(cat Downloads/datei.csv | wc -l)
for((i=115;i<=122;i++)); do
line_get=$(sed -n $i"p" Downloads/datei.csv)
if [[ -z "$line_get" ]];
then
echo "$i is empty"
else
echo "$i is NOT empty"
fi
done
If you need to dynamic generate the variable name. Try this:
declare "line$i=$(sed -n $i"p" Downloads/datei.csv)"
var="line$i"
echo "${!var}"
And echo "line$i"; just print the text like line115 but not the value of the variable line$1.

Simple bash script output [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 9 months ago.
I try to write simple script to read temperature:
cpu=$(cat /sys/class/thermal/thermal_zone*/temp)
if [$cpu -ge 50000]; then
echo "OK"
else
echo "Not OK"
fi
echo $cpu is fine: 64000 but script output is:
myscript.sh: 2: [64000: not found
Not OK
What is wrong with line 2?
Thank You.
You want to make a few changes here:
Add a space between the [ and the $cpu, and before the ] (as per the comments above)
Place the $cpu into double quotes, to avoid unexpected results
Handle the possibility of maximum values, by picking up the maximum (or minimum, or average).
cpu="$(cat /sys/class/thermal/thermal_zone*/temp | sort -nr | head -1)"
if [ "$cpu" -ge 50000 ] ; then
echo "OK"
else
echo "NOT"
fi
If you prefer the space-less expressions, you can use the arithmetic expressions
cpu="$(cat /sys/class/thermal/thermal_zone*/temp | sort -nr | head -1)"
if ((cpu>50000)) ; then
echo "OK"
else
echo "NOT"
fi

Bash loop not adding to array [duplicate]

This question already has answers here:
A variable modified inside a while loop is not remembered
(8 answers)
Closed 2 years ago.
I am trying to add elements to an array in bash. I am querying and looping over the query.
delete_arr=()
delete_arr+=("test")
mysql -e "$sql_statement" | while read directory_name; do
if [ $counter -gt 0 ]
then
delete_arr+=($directory_name)
fi
let counter=counter+1
done
for i in "${delete_arr[*]}"; do echo "$i"; done
The only output I am getting is test. I should be getting a lot more data. The query works and the data gets added to the array in the loop however when I jump out of the loop the array only contains test.I am doing nothing to reset the array.
In the pipe, you are implicitly creating a new subshell with its own namespace. Try avoiding the pipe:
delete_arr=()
delete_arr+=("test")
while read directory_name
do
if [ "$counter" -gt 0 ]
then
delete_arr+=("$directory_name")
fi
counter=$((counter+1))
done < <(mysql -e "$sql_statement")
for i in "${delete_arr[#]}"; do echo "$i"; done

bash - setting variable value is not working [duplicate]

This question already has answers here:
A variable modified inside a while loop is not remembered
(8 answers)
Closed 5 years ago.
Problem
My bash script loops through a bunch of files and if it finds an unexpected file that contains some text, it sets an error flag and is supposed to exit the loop. The problem is that when i evaluate the error condition after the loop, the error flag isn't set properly.
I can't seem to see where the bug is.
Code
#!/bin/sh
valid=1
grep -rs -L 'bogustext' * | while read line; do
echo "Processing file '$line'"
if [ "$line" != "arc/.keep" ] && [ "$line" != "arc/prp/lxc" ] && [ "$line" != "arc/lbb/lxc" ]; then
valid=0
echo "just set it to zero - $valid"
break 2
fi
done
echo "$valid"
if [ "$valid" -eq 0 ]; then
echo "1..1"
echo "not ok $line invis malformed"
else
echo "1..1"
echo "ok"
fi
Here's the output which shows the problem / bug. As you can see, there is an extra file in the list that contains the bogus string "arc/ttp". The script sets the "valid" variable to 0 but by the time I'm ready to evaluate it to display the right status, it's still the original value.
lab-1:/var/vrior# sh test.sh
Processing file 'arc/.keep'
Processing file 'arc/prp/lxc'
Processing file 'arc/lbb/lxc'
Processing file 'arc/ttp'
just set it to zero - 0
1
1..1
ok
What I've tried so far
I'm currently googling to see if in Bash there's local variables vs. global. Not too sure, but if you see my bug, please let me know.
Pipes create subshells, so $valid inside the loop refers to a new variable, which disappears before you try and use it.
Since you've tagged bash, then you can use a process substitution instead of the pipe:
while read line; do
echo "Processing file '$line'"
if [ "$line" != "arc/.keep" ] && [ "$line" != "arc/prp/lxc" ] && [ "$line" != "arc/lbb/lxc" ]; then
valid=0
echo "just set it to zero - $valid"
break 2
fi
done < <(grep -rs -L 'bogustext' *)

Resources