This question already has answers here:
How can I wait for certain output from a process then continue in Bash?
(5 answers)
Closed 1 year ago.
I'm executing a command in a bash shell and need to wait until a command echos a string. This is the pseudo code for what I have in mind. What do I set currentline to such that the until loop exits when the text output I'm waiting for echos?
currentline=""
until [[$currentline | grep -m 1 "the text output I'm waiting for"]]; do
echo " == Waiting for the text == "
currentline=???
sleep 1;
done
EDIT: the text output I'm waiting for tells the script the executed command is ready to receive input. The command does not terminate after the text output I'm waiting for. I want the script to stop sleeping and continue.
EDIT #2: The script runs on a remote CI/CD service, Codemagic, so I don't think I can use tail or any command that needs the path to the log file? (As described here)
So just:
while IFS= read -r line; do
if [[ "$line" == "the text .... " ]]; then
break;
fi
done < <(your-cmd)
if you want to keep your-cmd running, use coproc.
coproc your-cmd
while ..... as above ...
done <&"${COPROC[0]}"
Related
I will first write a sequence of commands which I want to run
echo <some_input> | <some_command> > temp.dat & pid=$!
sleep 5
kill -INT "$pid"
The above is working perfectly fine when i run it one by one from bash shell, and the contents in the temp.dat file is exactly what I want. But, when I create a bash script containing the same set of commands, I am getting nothing in the temp.dat file.
Now, I'll mention why I'm writing those commands in such a way:
<some_command> asks for an input, that's why I'm piping <some_input>
I want the output of that command in a separate file, that's why I've redirected the output.
I want to kill the command by sending SIGINT signal after some time.
I've tried running an interactive shell by writing #!/bin/bash -i in the first line of the shell script, but it's not working.
Any alternate method to achieve the same results will be appreciated.
Update: <some_command> is also invoking a python script, but I don't think that this will cause it to behave differently.
Update2: python script was the only cause of that different behavior.
One likely cause here is that your Python process may not be flushing stdout within the allowed five seconds of runtime.
export PYTHONUNBUFFERED=1
...will cause content to be promptly written, rather than waiting for process exit / file close / amount of buffered content to reach a level sufficient to justify the overhead of a flush operation.
will this work for you?
read -p "Input Data : " inputdata ; echo $inputdata > temp.data ; sleep 5; exit
obvs
#!/usr/bin/env bash
read -p "Input Data : " inputdata
echo $inputdata > temp.data
sleep 5
should work as a script
to suit :D
#!/usr/bin/env bash
read -p "Input Data : " inputdata
<code you write eg echo $inputdata> > temp.data
sleep 5
I am trying to create my first bash script:
echo "What file are we looking for: "
read FILE
while [ 1 ]
do
ls -lah | grep $FILE
sleep 1;
clear
# Some way to detect user input
if [ user-input ]
then
echo "Input found"
exit 1;
fi
done
Is there a way to look for user input without pausing the program? When I used read input before the if statement, the program stopped until input was...inputted.... The program is supposed to continuously output the file I am look using ls and clear so I can monitor the size as it grows, but when the user inputs any key stroke the program exits.
Like I said this is my first bash script, I do know python pretty well and understand 'coding' but not bash.
Thanks
check Bash input without pausing the script?, seems like a duplicate.
from that link:
read -t0 can be used to probe for input if your process is structured as a loop
#!/bin/bash
a='\|/-'
spin()
{
sleep 0.3
a="${a:1}${a:0:1}"
echo -n $'\e'7$'\r'"${a:1:1}"$'\e'8
}
echo 'try these /|\- , dbpq , |)>)|(<( , =>-<'
echo -n " enter a pattern to spin:"
while true
do
spin
if read -t0
then
read a
echo -n " using $a enter a new pattern:"
fi
done
else you could run one command in the background while promptiong for input in the foreground. etc...
This question already has answers here:
Does $! mean something in shell scripting
(3 answers)
Closed 4 years ago.
I've been working on Shell and I've seen something like :
pid_A2=$!
wait $pid_A2
pid_A2=$?
Would you please explain the difference between the two syntax "$!" and "$?"...
Actually, i know that $? is the exit status of the previous command but I've never seen the previous one.
$?: the status of the last process execution
$!: the pid of the last command in background
$! is the last job of the background process. For example:
$ sleep 1000 &
[1] 6646 ---> process id
echo "$!" will print the process id of the last command (here, 6646).
$? returns the exit value of the command which is recently executed. $? is used when we want to handle the return value of a command or function. For example:
if [ **$?** -eq 1 ];
then
# do something
fi
This question already has answers here:
Shell script while read loop executes only once
(6 answers)
While loop stops reading after the first line in Bash
(5 answers)
Bash script stops execution of ffmpeg in while loop - why?
(3 answers)
Closed 5 years ago.
I have a while loop that should iterate over a text file but stops at the first line and I can't figure out why. My code is below.
while read hadoop_accounts; do
if ! grep "no lock no remove"; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >> missing_no_lock_no_remove.txt
fi
done < hadoop_accounts.txt
When grep is run with no explicit redirection or file to read, it reads stdin. All of stdin. The same stdin your while read loop is reading from.
Thus, with all your stdin consumed by grep, there's nothing left for the next read command to consume.
The easy approach (and much better for performance) is to do the substring check internal to the shell, and not bother starting up a new copy of grep per line processed at all:
while IFS= read -r hadoop_accounts; do
if ! [[ $hadoop_accounts = *"no lock no remove"* ]]; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
fi
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt
Note also that we're only opening the output file once, not re-opening it every single time we want to write a single line.
If you really want to call grep over and over and over with only a single line of input each time, though, you can do that:
while IFS= read -r hadoop_accounts; do
if ! grep "no lock no remove" <<<"$hadoop_accounts"; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
fi
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt
Or, even better than either of the above, you can just run grep a single time over the entire input file and read its output in the loop:
while IFS= read -r hadoop_accounts; do
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
done < <(grep -v 'no lock no remove' <hadoop_accounts.txt) 3>>missing_flags.txt
This question already has an answer here:
Why command "read" doesn't work?
(1 answer)
Closed 6 years ago.
I am trying to get a user input inside a while loop in a shell script.
ls| while read p
do
echo $p
read key
done
I cannot read the input from stdin(keyboard) because my input is piped through ls.
Can someone help me to get a user input inside the loop?
You can read from stdin using file descriptor 0. or by just using /dev/tty . Where $$ is pid of your current process.
ls| while read p
do
echo $p
read key < /proc/$$/fd/0
# OR read key < /dev/tty
done