How to do a while loop with a string redirected into it
You had the right idea with your 2nd snipit but you need to use 'Here Strings' via the <<<
syntax. You cant access $TEST_STRING
outside of your first snipit because the pipe creates a sub-shell; using the here-string does not. Also, make sure you quote "$HTTP_LINKS"
otherwise you'll lose the newlines.
#!/bin/bash
HTTP_LINKS=$(echo -e "http://www.aaa.com\nhttp://www.bbb.com")
unset TEST_STRING;
while read url;
do
((TEST_STRING++))
done <<<"$HTTP_LINKS"
echo $TEST_STRING
Output
2
C - Reading a string & int from stdin (or redirect from file)
You need to allocate memory for str, try char str[256]
instead of char * str.
Also remove the scanf from the bottom of the while loop, it's not necessary.
using input redirection in while loop
The idiomatic way to read a sequence of white-space separated integers in C++ would be
#include <iostream>
using namespace std;
int main () {
int input;
while (cin >> input) {
cout << input + 1 << endl;
}
return 0;
}
Let's come to why this works the way it does.
cin >> input
discards possible white-space and then reads an integer from the standard input. Moreover, it returns a reference of the cin object used. With this returned reference, you can call the bool
conversion operator to check if any of the fail bits is set in the given std::basic_ios
object. So
while (cin >> input)
does two things. Read an integer from standard input and check if it successfully completed the operation. As long as this operation succeeds, your while loop continues to iterate and you print the numbers.
See http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt for reference on std::basic_istream::operator>>
.
See http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool for reference on operator bool
.
Edit1: Move references to bottom so that the answer is more readable.
Variable loss in redirected bash while loop
First of all, simplify your script! Usually there are many better ways in bash. Also most of the time you can rely on pure bash solutions instead of running awk or other tools.
Then add some debbuging!
Here is a bit refactored script with debugging
#!/bin/bash
for ip in "$(ifconfig | grep -oP 'inet addr:\K[0-9.]+')"
do
bytesin=0
bytesout=0
while read -r line
do
read -r subIp _ _ increment _ <<< "$line"
if [[ $subIp == "$ip" ]]
then
((bytesout+=increment))
else
((bytesin+=increment))
fi
# some debugging
echo "line: $line"
echo "subIp: $subIp"
echo "bytesin: $bytesin"
echo "bytesout: $bytesout"
done <<< "$(pmacct -s | grep "$ip")"
echo "$ip $bytesin $bytesout" >> /tmp/bwacct.txt
done
Much clearer now, huh? :)
File redirection for loops in the shell
There's only one stdin
that you redirect in the loop. Both read
and awk
will read from that stdin
. While the read
only consumes one line (the first), awk
happily consumes the rest.
In the next iteration, read
has nothing more to read and the loop terminates.
If you want to provide data on awk
's stdin, you must do so explicitly, e.g. by piping into awk
with printf '%s\n' "$line" | awk ...
.
How to redirect grep to a while loop
The problem is in this line:
done << (grep -w "token" "$file")
# ^^
You need to say <
and then <()
. The first one is to indicate the input for the while
loop and the second one for the process substitution:
done < <(grep -w "token" "$file")
# ^ ^
Note however that there are many others things you want to check. See the comments for a discussion and paste the code in ShellCheck for more details. Also, by indicating some sample input and desired output I am sure we can find a better way to do this.
Redirecting output of bash for loop
Remove your semicolon.
for i in `seq 2`; do echo "$i"; done > out.dat
SUGGESTIONS
Also as suggested by Fredrik Pihl, try not to use external binaries when they are not needed, or at least when practically not:
for i in {1..2}; do echo "$i"; done > out.dat
for (( i = 1; i <= 2; ++i )); do echo "$i"; done > out.dat
for i in 1 2; do echo "$i"; done > out.dat
Also, be careful of outputs in words
that may cause pathname expansion.
for a in $(echo '*'); do echo "$a"; done
Would show your files instead of just a literal *
.
$()
is also recommended as a clearer syntax for command substitution in Bash and POSIX shells than backticks (`
), and it supports nesting.
The cleaner solutions as well for reading output to variables are
while read var; do
...
done < <(do something)
And
read ... < <(do something) ## Could be done on a loop or with readarray.
for a in "${array[@]}"; do
:
done
Using printf can also be an easier alternative with respect to the intended function:
printf '%s\n' {1..2} > out.dat
Improve bash script to echo redirect within loop
When the redirection is inside the loop the output file is opened and closed every single iteration. If you redirect the entire loop it's opened for the duration of the loop, which is much, much faster.
for ((i = 0; i < 1000000; ++i)); do
echo "test statement redirected into file a million times"
done > /tmp/output.txt
(Note also the updated loop logic.)
If you want to make it even faster, you can speed it up by simplifying this to one or two commands that loop internally rather than looping in the shell script. yes
will output a fixed string over and over. Combine it with head
to control how many lines are printed.
yes 'test statement redirected into file a million times' | head -1000000 > /tmp/output.txt
Will mounting the tmp directory in RAM make it faster?
Maybe, but I wouldn't bother. That's a system-wide change for a local problem. If you don't need the file on disk, it raises the question: do you even need to create the file in the first place? Why do you need a file with the same line repeated a million times? Maybe this is an XY problem. Perhaps you don't need the file at all.
For instance, if you're creating it and immediately passing it to a single subsequent command, you could try using process substitution instead to avoid needing a temp file.
yes 'test statement redirected into file a million times' | head -1000000 > /tmp/output.txt
command /tmp/output.txt
becomes
command <(yes 'test statement redirected into file a million times' | head -1000000)
Related Topics
How to Update Minikube Latest Version
Using Output of Previous Commands in Bash
What Is Eof!! in The Bash Script
Os X Permission Denied for /Usr/Local/Lib
Openssl/Rsa - Using a Public Key to Decrypt
On-The-Fly Output Redirection, Seeing The File Redirection Output While The Program Is Still Running
Check If All Lines from One File Are Present Somewhere in Another File
Securing Udp - Openssl or Gnutls or ...
Linux: How to Debug a Sigsegv? How to Trace The Error Source
Why Processes Are Deprived of CPU for Too Long While Busy Looping in Linux Kernel
Docker Run Hello-World Still Fails, Permission Denied
How to Pass Env Variables Between Make Targets
Principle of Qemu CPU Emulation
How to Disable Serial Console(Non-Kernel) in U-Boot
Ansible: Check If Service Is Listening on a Specific Port
How to Programmatically Invert Screen Colors in Linux
How to Find The Memory Consumption of a Particular Process in Linux for Every 5 Seconds