Looping in bash [duplicate] - linux

This question already has answers here:
while loop to read file ends prematurely
(4 answers)
Closed 7 years ago.
I have a do-while loop in bash, and it runs the body once but no more.
while read id; do
bash ./setup_instance.sh "${id}"
echo "Ran setup_instance"
done < ids.txt
echo "Finished of loop"
The file ids.txt has two lines, one "ID" string per line. I tested this by replacing the line inside the loop with echo "ID: ${id}" and the loop works.
Also, note that the code does get to the two echo lines, so it is not the case that invoking the script throws us out of the execution.
What am I doing wrong?

When running
while read id; do
echo "Ran setup_instance ${id}"
done < ids.txt
echo "Finished of loop"
with ids.txt:
abc
bcd
I get the expected output (with the two lines).
They is a chance that your last line does not contain a linefeed (\n)
Can you check by running cat -A ids.txt
It should echo
abc$
bcd$
If the second dollar is missing, try running dos2unix ids.txt to add the missing newline (or add it manually)

Related

How to format linux mpstat output in multiple lines [duplicate]

This question already has answers here:
Capturing multiple line output into a Bash variable
(7 answers)
Closed 3 years ago.
I have a small script where I appended the output of linux mpstat to a log file.
#/bin/bash
CPU_USAGE=$(mpstat)
echo $CPU_USAGE >> temp.log
The problem is that the output of mpstat on the terminal is formatted properly in 3 lines like so
However, the output to the file is all in one line.
How do I format the output like the one on the terminal?
Just quote the variable so it is not seen as several different parameters to be printed one after the other:
echo "$CPU_USAGE" >> temp.log
You could just directly pipe the output to the file:
#!/bin/bash
mpstat >> temp.log
If you must store it in a variable, then quote it like:
#!/bin/bash
CPU_USAGE=$(mpstat)
echo "$CPU_USAGE" >> temp.log
Otherwise, bash will not interpret the newlines as part of the message to echo, but the whole output as a list of short strings to output.

cannot modify variables inside bash script case statement using while [duplicate]

This question already has answers here:
A variable modified inside a while loop is not remembered
(8 answers)
Closed 3 years ago.
I have s simple bash script as follow:
interval=""
cat conf.param|\
while read param
do
item_=$(echo $param|cut -d "=" -f1)
case ${item_} in
interval)
interval=$(echo $param|cut -d "=" -f2)
echo $interval
;;
method)
method=$(echo $param|cut -d "=" -f2)
;;
esac
done
echo "${interval}"
It reads the contents of a file and stores them in different variables. the issue is that the variables are not set properly inside case segment. I put two echos. The first one (inside case) displays the interval value correctly which is '2', but the second one just after the esac statement displays nothing! it shows an empty blank line.
the conf.param is a simple text file. it has more lines I only printed two lines:
interval=2
method="POST"
Your problem is that using a pipe ("cat conf.param | while read param"), you call a second shell which can not export its variables to the calling one. See this example:
interval=""
cat tmp.txt | while read param; do ##### DON'T DO THIS
interval="A$interval"
done
echo "First attempt: $interval"
interval=""
while read param; do
interval="A$interval"
done < tmp.txt ##### BUT DO THIS INSTEAD
echo "Redirection attempt: $interval"
The file tmp.txt contains 4 lines; the output of the script is:
First attempt:
Redirection attempt: AAAA
As you see, the first attempt retains the old value of interval. The second/redirection attempt instead works because no new process is created.

How to echo this entire code to .bashrc without leaving out characters/strings? [duplicate]

This question already has answers here:
How do I properly quote this bash pipeline for watch?
(2 answers)
Closed 3 years ago.
How can I echo this entire piece of code to .bashrc without leaving out a single character?
# automatic logging of terminal input/output
test "$(ps -ocommand= -p $PPID | awk '{print $1}')" == 'script' || (script -f -q /home/user/.logs/terminal/manjaro/$(date +"%Y-%m- %d_%H:%M:%S")_terminal.log)
When I attempt to enter the following into terminal:
echo "the above code" >> ~/.bashrc
I get the following appended to .bashrc which is nothing like "the above code", its short about 45 or so characters.
# automatic logging of terminal input/output
test script == 'script' || (script -f -q /home/user/.logs/terminal/manjaro/2019-05- 08_09:09:19_terminal.log)
As you can see, it's leaving out A LOT of the original code. I understand this has a lot to do with the number of different quotations and placement, but without altering my code much, or at least to the point where it can still function as its intended, how can I go about getting this to echo to the file properly?
Thank you for every nanosecond of your time.
Wrap your echo'd string with single quotes ' instead of double "

Syntax error: operand expected (error token is “+”) (i coudn't resolve this problem with the other thread) [duplicate]

This question already has answers here:
Why does a space in a variable assignment give an error in Bash? [duplicate]
(3 answers)
How to loop over directories in Linux?
(11 answers)
How to assign the output of a Bash command to a variable? [duplicate]
(5 answers)
Closed 4 years ago.
I cant get this simple program working the code looks like this because is for a class exercise I wouldn't do it like that but I have to, sorry if the code is a mess but I've tried so many things that the code is a bit "deformed"
n= 0
for x in /home
do
e= du $x -B1 | cut d" " -f 1
$sum$(($sum+$e))
done
echo $sum
At line 1 you have a space between the '=' and the 0, but there shouldn't be a spaces either before or after the '=' in an assignment.
At line 4 happens the same, but also you missed the backticks '`' around the commands, that indicate bash to evaluate what is inside the backticks and return the output of that command.
At line 5 it says:
$sum$(($sum+$e))
So did you mean:
sum=$(($sum+$e))
Update: I have found three problems more:
In line 2, replace /home with /home/*, because the former only uses /home in the loop, and the later returns every directory (and file) in the /home directory.
You are passing d" " to cut, the correct option is -d " ".
Also, du output is formatted with tabs, not spaces. If you delete the -d " " in cut, it works.

Bash shell script update and print a variable overwriting the same line [duplicate]

This question already has answers here:
Displaying only single most recent line of a command's output
(2 answers)
Closed 5 years ago.
I been trying to print a variable in the same time for a scrip that pretends automatize a process the content is the output of this
sed "s/Read/\n/g" /tmp/Air/test.txt | tail -1 test.txt | grep ARP
so i put this in a while loop
do
out= sed "s/Read/\n/g" /tmp/Air/test.txt | tail -1 test.txt | grep ARP
echo -n "$out"
sleep 1
done
i read other questions here and i try with different option like echo -ne, echo -ne "$out" \r, printf "\r" or printf "%s" and no luck with no one, all the other example don't have a variable to print just counter o system variables
Update
it seems to appear that the echo -n repeat $out in the same line, if out="this is a test" the output of echo -n is "this is a test this is a test this is a test this is a test ...." maybe im missing some option ?
Update 2
sorry for the miss understood perhaps i was not very clear but what i want is overwrite the same line with the value of $out, the source of $out is the output of the aireplay-ng command that executes along with the script and i get the output with
the ouput is something like this
102415 packets (got 5 ARP requests and 15438 ACKs), sent 37085 packets...(499 pps)
but the number of ARP request is changing constantly
this code for example use echo -ne and overwrite in the same line
#!/bin/bash
for pc in $(seq 1 100); do
echo -ne "$pc%\033[0K\r"
sleep 1
done
the output of this is like a percent indicator that shows "10%" and going instead of "1% 2% 3% 4% 5% .." in the same line and i already try like this but with no luck
if you are trying to execute the sed Please use
`sed "s/Read/\n/g" /tmp/Air/test.txt | tail -1 test.txt | grep ARP`
First of all you are assigning a value of bash command wrongly to variable.
out=$(sed "s/Read/\n/g" /tmp/Air/test.txt | tail -1 test.txt | grep ARP)
Then you can print all your output in one line as you wrote:-
echo -n $out
The recent addendum to your question reads like you're miscommunicating your intent: this is a test this is a test this is a test is what a plain reading of your question indicates you to be asking for (printing this is a test over and over in a loop without newlines, after all, can be expected to do nothing else); why you'd describe this in a context that makes it sound like a bug is thus surprising.
If you want to send the cursor back to the beginning of your current line and overwrite that line, that might be something like the following:
#!/bin/bash
# ^^^^ not /bin/sh; this enables bash extensions
# ask the shell to keep $COLUMNS up-to-date
shopt -s checkwinsize
# defaults to 80-character terminal width, but uses $COLUMNS if available
printf "%-${COLUMNS:-80}s\r" "$out"`
...which prints your string, pads out to 80 characters with spaces, and then returns the cursor to the beginning of the line, such that the next thing you write will overwrite that string.
Of course, if you print that line and then return to a shell prompt, the prompt will start at the beginning of the same line and overwrite the text, so be sure to follow up with an echo.

Resources