Problems with while in bash [duplicate] - bash

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 4 years ago.
I am doing a bash script with the web api of checkpoint.
126: No such file or directory
this error refers to line 25 in which I have the next sentence:
while [$reglas < $n_reglas ];do
I have tried changing that to:
while [$reglas -lt $n_reglas ];do
but the error persist and I am not sure of what is the real problem.
The variables are defined like this:
reglas=1
n_reglas=$(echo $rulebase_list | jq '.total')
and I have printed their value in order to check that they are taking the correct value. Any idea of which is the problem?
Thanks!

Unfortunately it is not very clear what the actual problem is. Please try to reproduce the problem in a small code snippet that we can execute and troubleshoot. This way we don't need to guess and can provide more precise help.
Here is a small snippet with a ton of assumptions.
reglas=1
n_reglas=4 # https://jqplay.org/s/BCTXyJ4NLc
while [ $reglas -lt $n_reglas ]; do
echo $reglas
reglas=$(($reglas+1))
done
# $bash -f main.sh
# 1
# 2
# 3

Related

Please explain what is happening with this 2 lines of bash code [duplicate]

This question already has answers here:
Assigning default values to shell variables with a single command in bash
(11 answers)
Closed 3 years ago.
im trying to learn bash right now, came across a script and im not 100% sure if i read it right.
source_dir_123=${SOURCE_DIR:-/tmp}
echo source_dir_123=$source_dir_123
What is happening here? I guess this is some kinda variable assigment, but it looks weird to me.
What type of assigment/operation happens here? Any specific name of these types of assignments?
Sorry for a newbish question, but i dont get it why would you use these kinda of assignments instead of something more straight forward like
source_dir_12="/tmp"
/tmp is the default value for source_dir_123 in case SOURCE_DIR is not set, then you're displaying the result to the console.
See the following example:
> echo $SOURCE_DIR
> source_dir_123=${SOURCE_DIR:-/tmp}
> echo source_dir_123=$source_dir_123
source_dir_123=/tmp
# now let's set SOURCE_DIR
> SOURCE_DIR=/test
> source_dir_123=${SOURCE_DIR:-/tmp}
> echo source_dir_123=$source_dir_123
source_dir_123=/test

Add incremental zero padding to filenames [duplicate]

This question already has answers here:
Batch rename sequential files by padding with zeroes
(10 answers)
Closed 4 years ago.
I'm running into an issue where I have a directory of files names:
something1.exr
something2.exr
something3.exr
and I need them named like
projectname.0000001.exr
projectname.0000002.exr
projectname.0000003.exr
I've come up with this:
NAME=image_test_GAM_4778x1806 c=1; for i in *.exr; do mv "$i" `printf $NAME."$c".exr`; let c=c+1; done
and it is able to rename files like:
image_test_GAM_4778x1806.1.exr
image_test_GAM_4778x1806.2.exr
image_test_GAM_4778x1806.3.exr
However, I need the incremented number to have 7-digit padded zeros so I found I can do that with "%07d", therefore I assume this code should work:
NAME=image_test_GAM_4778x1806 c=1;
for i in *.exr; do
mv $i $(printf “%s.%07d.exr” “$NAME” “$c”);
let c=c+1;
done
But it doesn't work and complains I'm using mv incorrectly. I know theres something wrong but logically it should make work, I'm trying to pass $NAME and $c to “%s.%07d.exr” respectively.
Can someone point me in the right direction? Any help would be appreciated.
Thank you.
Using rename utility with a perl expression:
rename -n "s/something(\d+)(.*)/'projectname.' . sprintf('%07d', \$1) . \$2/ge" *.exr
Using -n flag is useful to test until you found the exact expression:
something10.exr renamed as projectname.0000010.exr
something1.exr renamed as projectname.0000001.exr
something2.exr renamed as projectname.0000002.exr
something3.exr renamed as projectname.0000003.exr
Thanks to Barmar's suggestion in the comments - this was an issue with curly quotes.
I changed the quotes to regular parallel quotes and it works.

bash: accessing global variables from a command pipeline [duplicate]

This question already has answers here:
A variable modified inside a while loop is not remembered
(8 answers)
Closed 6 years ago.
I want to fill an associative array in bash in somewhat non-trivial setup. I have a pipeline of commands to produce the required input for the array.
Here is a minimal/toy example:
declare -A mapping
seq 10 | while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
In this example mapping is changed inside while, but these changes do not propagate into the global namespace. I think this is because while works inside a separate subshell, thus namespaces have diverged.
In order to avoid (what I suggest) the problem with subshells, I came up with the following:
declare -A mapping
while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done < <(seq 10)
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
Thus, the generation part explicitly goes into a subshell, while the while loop left at the top-level alone. The construction works.
My questions are: is there any better way to accomplish my goal? And, is my suggestion about subshells correct? If so, why bash uses a subshell in the first case, but not in the second?
EDIT: after little more digging, the question mostly is a duplicate of this one. A good list of options to handle the issue could be found at http://mywiki.wooledge.org/BashFAQ/024
Not sure if this is a better way than your second code snippet, but a way to solve the first one is to use sub shell { ... } right after the pipe:
declare -A mapping
seq 10 | {
while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
}

Super Simple bash If (variable > integer) treating (variable as a command [duplicate]

This question already has answers here:
Getting "command not found" error while comparing two strings in Bash
(4 answers)
Closed 6 years ago.
I feel like this should be really simple but I can't get past this step.
$num = 5
if [$num > 2]; then echo greater; fi
the problem is, I keep getting [5: command not found.
Why is it not evaluating the if [ test ] block correctly? It's like the shell forgot about the if and just moved on to "hey, [5 > 2 does not look like a command, I can't find [5"... but [5 isn't a command, it's part of the if test block?
I have tried using different brackets and using -gt instead of >. The problem is bash doesn't actually ever do the test. For some reason it ignores if.
Just managed to find the answer:
if compare strings get a "command not found"-Error
really unexpected, there needs to be a space between the [ brackets and the variable.
I would never have guessed.

Weird behavior in bashrc: concatenate, same code run/fail [duplicate]

This question already has answers here:
Bash syntax error: unexpected end of file
(21 answers)
Closed 6 years ago.
I have a VM with CentOS 6 and I am loading some scripts from bashrc.
Everything worked fine, but I wanted to copy-paste the same code and scripts in an older backup of same VM, but I got an error: "unexpected end of file". Also the same error had to deal another person when I wanted to share those scripts with him (he had the same VM).
So I started to debug a little and found that one row he didn't liked it was (it was parsing an array:
COUNTER=1
while [[ ! -z ${SCRIPT[$COUNTER]} ]]; do
Also he didn't liked this either (it's not exactly the same with "while" logic, but it does the job):
for i in ${Script[#]}; do
So, I replaced it with:
for ((i = 0; i < ${#SCRIPT[#]}; i++)); do
Now I tryed to get the error name with same piece of code and no more errors occurred.
Also I have this behavior which is the weirdest from all:
Code:
BASH_SCRIPTS_LOCATION='/mnt/hgfs/Shared-workspace/scripts/'
SCRIPT[0]='aliases.sh'
SCRIPT[1]='scripts_config.sh'
SCRIPT[2]='credentials.sh'
SCRIPT[3]='other_functions.sh'
SCRIPT[4]='ssh_functions.sh'
SCRIPT[5]='release_functions.sh'
SCRIPT[6]='test_functions.sh'
for ((i = 0; i < ${#SCRIPT[#]}; i++)); do
loadedScript=${BASH_SCRIPTS_LOCATION}${SCRIPT[$i]}
echo -e "$loadedScript"
done
Terminal output (seems the "concatenate" it is replacing the characters starting from the begging of first String/variable :
aliases.shShared-workspace/scripts/
scripts_config.shworkspace/scripts/
credentials.shed-workspace/scripts/
other_functions.shorkspace/scripts/
ssh_functions.sh-workspace/scripts/
release_functions.shkspace/scripts/
test_functions.shworkspace/scripts/
I think I am using something very inappropriate. But I am not sure what or what I should be looking for.
Any recommandation or advice is welcome.
Thanks!
It doesn't show here but your script has carriage return chars in the shell definition lines. Edit them out (using Notepad++ for instance or tr -d "\015" < yourscript.sh > newscript.sh)
You can redirect your script to a file you'll see all the text in the file.
Carriage return char (asc 13, \r) just resets the cursor without skipping to newline. Every text written after that overwrites the text in the current line. Windows uses that to complement the linefeed character. Windows text mode is like that

Resources