2

Linux: Red Hat Enterprise Linux Server release 6.5 (Santiago)

BASH: GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

One of the VM that I just provisioned is still waiting for the DNS to update it's node entries and one the node has a NAS which is mounted on at /project_support folder. It takes around 5-10 minutes for /project_support folder to be accessible, yea bad I know.

For my automation not break due to this issue and I didn't want to add a constant sleep NNN, I used until loop so that until the mount is mounted and /project_support folder is available, I wanted to sleep for 5 seconds and check for folder existence before proceeding further in the automation script/logic.

Why the first until loop is continuing and not exiting on the condition check when cd command to a given folder is successful aka exit status 0? The second until is working as expected.

For the 2nd until loop, even if I create the folder (from a second terminal, while until loop is running), it still doesn't break the until loop.

[root@nukaserver01 ~]# cd /project_support; echo $?
0
[root@nukaserver01 project_support]# pwd
/project_support

[root@nukaserver01 project_support]# until [ `cd /project_support` ]; do echo '-- sleep 5'; sleep 5; done
-- sleep 5
-- sleep 5
-- sleep 5
^C

[root@nukaserver01 project_support]# until [ `cd /project_support-I-DONT-EXIST-AT-ALL` ]; do echo '-- sleep 5'; sleep 5; done
-bash: cd: /project_support-I-DONT-EXIST-AT-ALL: No such file or directory
-- sleep 5
-bash: cd: /project_support-I-DONT-EXIST-AT-ALL: No such file or directory
-- sleep 5
^C
[root@nukaserver01 project_support]#

Why is this issue getting fixed when I do: ?

until [ `cd /project_support && pwd` ]; do ...; ...; done
AKS
  • 16,482
  • 43
  • 166
  • 258

2 Answers2

4
until [ `cd /project_support` ]

The backticks capture cd's output, which is an empty string whether or not the named directory exists (error messages are printed to stderr and aren't captured). The square brackets then test if that string is empty, which it always is.

Unnecessary square brackets is a common shell scripting malady. Get rid of them and the backticks.

until cd /project_support; do
    ...
done

Note that since cd is no longer being executed in a sub-shell it will actually take effect when it succeeds. To prevent that you can add an explicit sub-shell:

until (cd /project_support); do
    ...
done

Or if you're just waiting until the directory exists, check that directly:

until [[ -d /project_support ]]; do
    ...
done
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Thx. The situation is like doing `ls -l /project_folder` shows it exists, doing `cd /project_folder` errors out, but when after few minutes it does work, if I do `mkdir -p /project_folder/dir1/subdir2` it errors out by saying: `mkdir: cannot create directory '/project_folder': File exists` (not sure why it didn't reflect dir1/subdir2 in the error mesg) i'm poking into it but I'll use the idea as you listed above. Due to this Jenkins jobs fails: `02:15:45 Build step 'Execute shell' marked build as failure` – AKS Nov 06 '18 at 18:30
2

You are returning and testing an empty string, which always evaluates as false.

until [ "" ] ; do sleep 1; date; done
Tue, Nov 06, 2018 12:03:17 PM
Tue, Nov 06, 2018 12:03:18 PM
Tue, Nov 06, 2018 12:03:19 PM
. . . 

By adding the pwd it returns the directory name/path when the cd succeeds, which as a string eval's as true.

try this -

until [[ -d /project_support ]] # ...

that will test for the existence of a directory.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
  • Dang, I thought `cd /folder` will return `true` .. thx. The issue is `-d /folder` works, but `cd /folder` is not working in some cases – AKS Nov 06 '18 at 18:10
  • Probably will do something like `until [[ -d /project_folder && $(cd /project_folder && pwd) ]]` – AKS Nov 06 '18 at 18:20
  • ah. If that's what you want, you need to take the brackets off. `until cd /project_support; then ...` as per [John](https://stackoverflow.com/users/68587/john-kugelman). Don't wrap it in `[` or backticks at all. The result will be the same. – Paul Hodges Nov 06 '18 at 18:41