JDiMatteo
JDiMatteo

Reputation: 13130

Exit bash script within while loop

How do you exit a script from within a find piped while loop?

E.g. following exit just exits the piped subshell:

find some_directory -type d|while read dir_name; do
  if [ -w "$dir_name" ]; then
    exit 1
  fi
done

Upvotes: 3

Views: 1894

Answers (2)

markp-fuso
markp-fuso

Reputation: 33854

In bash an exit invoked in a subprocess will exit the subprocess but not the parent process.

In OP's code the pipeline - find | while - will run the while (and the subsequent exit invocation) within a subprocess, so if/when the exit 1 is invoked the subprocess will be exited but not the parent process.

To allow the exit to apply at the top level we need to insure the while is not run within a subprocess. Expanding on 123's comment:

while read -r dir_name; do
  if [ -w "$dir_name" ]; then
    exit 1
  fi
done < <(find some_directory -type d)

Note that the <( ) construct ("process substitution") is not available in all shells, or even in bash when it's in sh-compatibility mode (i.e. when it's invoked as sh or /bin/sh). So be sure to use an explicit bash shebang (like #!/bin/bash or #!/usr/bin/env bash) in your script, and don't override it by running the script with the sh command.

Upvotes: 4

William Pursell
William Pursell

Reputation: 212178

You can check the return status of the pipe:

if ! find some_directory -type d|while read dir_name; do
  if [ -w "$dir_name" ]; then
    exit 1
  fi
done; then exit 1; fi

Or, more simply:

 find some_directory -type d|while read dir_name; do
      [ -w "$dir_name" ] && exit 1
    done || exit 1

Upvotes: 5

Related Questions