Question

Coming from Powershell and trying to figure out how to do an equivalent sort of operation in bash.

Can someone please clarify for me how to do this? I've been researching for a bit with no luck

While **ls /etc/test | grep "test.conf" -q** -ne 0 ; do  
echo test  
sleep 2  
done

I am trying to make bolded section of the statement trigger first so that the resulting t/f can be evaluated.

Was it helpful?

Solution

What you really need is

until [ -f "/etc/test/test.conf" ] ; do
    echo test
    sleep 2
done

OTHER TIPS

The direct solution to your problem is that the (negated) exit status of grep is the only thing the while loop needs:

while ! ls /etc/test | grep -q "test.conf"; do

There is also the until loop which handles the negation for you:

until ls /etc/test | grep -q "test.conf"; do

However, this is a fragile (ls breaks in the case where a file name contains a newline) and expensive (multiple extra processes are created). Instead, let the shell check directly if the desire file exists yet:

until [[ -f "/etc/test/test.conf" ]]; do

(and we arrive at @anishane's original answer).


An even better approach, though, is to ask the operating system to tell us when the file is created, without having to ask ever two seconds. How you do this is necessarily OS-specific; I'll use Linux as an example. For this, you would need to install the inotify-tools package first.

The simplest thing is to just use a call to inotifywait:

inotifywait -c create /etc/test/test.conf

But if the file already exists, you'll wait forever waiting for it to be created. You might think, "I'll check if it exists first, then wait if necessary", with

[[ -f /etc/test/test.conf ]] || inotifywait -c create /etc/test/test.conf

but now we have a race condition: it's possible that the file is created after you look for it, but before you start waiting. So the full solution is to first wait for it to be created in the background, then kill the background job if the file does exist, then wait for the background to complete if it is still running. It sounds a little convoluted, but it's efficient and it works.

inotifywait -c create /etc/test/test.conf & WAIT_PID=$!
[[ -f /etc/test/test.conf ]] && kill $WAIT_PID
wait $WAIT_PID
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top