Linux script exit while

Bash Scripting – While Loop

A while loop is a statement that iterates over a block of code till the condition specified is evaluated to false. We can use this statement or loop in our program when do not know how many times the condition is going to evaluate to true before evaluating to false.

The syntax of a while loop in BASH is something like below:

while [ condition ]; do # statements # commands done

If the condition is true then the commands inside the while block are executed and are iterated again after checking the condition. Also if the condition is false the statements inside the while block are skipped and the statements after the while block are executed.

The example of a while loop is as follows:

#!/usr/bin/bash a=7 while [ $a -gt 4 ]; do echo $a ((a--)) done echo "Out of the loop"

As we can see that the loop is iterated till the condition is false. As soon as the variable a becomes 4, the condition is evaluated to false and the loop skips the command block and starts executing the commands after the block.

Reading a file with a while loop

We can read a file with a while loop in BASH. By parsing certain parameters to the while loop condition, we can iterate over the file line by line or by other groups like characters or words.

#!/usr/bin/bash file=temp.txt while read -r line; do echo $line done < "$file"

We use the command read to actually fetch the lines or characters from the file. The read command is passed with -r argument which ignores the escaping of characters if the \ appears and hence it is parsed as its. We read a line from a file mentioned after the done statement. The read command reads a line from the mentioned file and the while loops end when the last line from the file is read ( no line is left to read).

This is how we can read the contents of the file using a while loop in BASH.

Infinite while loop

To create an infinite loop using a while loop statement. We don’t need to put any condition in the while loop and hence the loop iterates infinitely. The below is the example of an infinite while loop:

#!/usr/bin/bash while : do echo "An Infinite loop" # We can press Ctrl + C to exit the script done

Thus the while loop in the script is going to iterate for infinite time. We can manually break the loop or the script by CTRL + C.

While loop to iterate for a fixed number of times

We can use a while loop to iterate over a fixed number of times, we can set the condition to be -le or less than equal to a number, and the loop will iterate till the iterator is less than or equal to the number provided in the condition. Also, we need to increment the iterator manually so to keep the loop iterator ticking, or else the loop will go on forever.

#!/usr/bin/bash i=1 # the number 4 can be the limit to # iterate the loop while [ $i -le 4 ]; do echo $i ((i++)) done

In the above example, we can see that the loop iterates a defined number of times. As we have initialized the counter to 1 and the condition is to iterate the loop till the iterator is less than or equal to the number in this case 4. Thus, we can change the number in the condition as per our requirement.

Читайте также:  Linux which driver is device using

Read the command-line argument with getopts options

We can use get ops options to read the input from the command line and if there are multiple arguments, we can check them and parse them one by one using a while loop. getopts is a tool to get user input from the command line, We can have multiple options to parse from the command line, and using getopts and while loops, we can make a professional-looking user input program.

#!/bin/bash while getopts n:a: OPT do case "$" in n) name=$;; a) age=$;; *) echo "Invalid option" exit 1;; esac done printf "My name is $name and am $age years old\n"

In this case, we have two options namely, the name and the age, you can have multiple options. We need to specify which option are we gonna use the switch case statements and from the command line using -shorthand option. In this case, we have used -n for name and -a for age. We also have a default or invalid case check to endure we do not parse wrong arguments. We can assign the value of the option using the OPTARG variable which parses the value provided to the option.

The while loop here is used to iterate till there are no options passed from the command line. We check for the -n and -a option and iterate till the carriage return or enter key is pressed and there are no further options to be parsed.

C-style while loop

We can use C-styled while loop in BASH, the variables need to be evaluated with BASH style but the overall syntax feels like C. We can use the operators like ,

In this example, we can see that the while loop has a condition with non-bash operators like -le, -ge, etc instead we use the C-styled operators in the condition. The rest of the loop is the basic loop as in BASH, the variable or iterator i is incremented by two as we can see in the last statement of the loop body. Thus the loop iterates over 5 times.

While loop to perform operations on a file

We can perform operations on a file, like reading only a particular part of a file. If we have columns that are formatted in a particular fashion, we can use variables to assign them and print them one row data time.

#!/bin/bash while read a b c do echo $b - $a done < wh.txt

In this example, we have three rows, we read the contents by assigning them to the variables a,b, and c, it can be anything you like but remember to use them in the loop body. We can select a particular column like b and a and can print or perform any operations on them. This won’t be reflected in the file though as they are just the local script variables.

Читайте также:  Port wine linux установка

Writing to a file using a while loop

We can write to a file by user input in a while loop. We can use the while loop to iterate till we manually exit out of the loop using CTRL + D by saving changes to the file or by CTRL + C for avoiding writing to the file. We use the read command to input the text from the command line and parse it to the file.

#! /bin/bash file=wh.txt echo "Enter the content into the file $file" while read line do echo $line >> $file done

So from the example above, we were able to enter text into a file using a while loop and read command. To exit out of the loop and save changes to the file, we use the CTRL+ D keys, and to exit out of the loop without saving anything into the file we can use the CTRL + C keys. Thus we enter the text from the command line to the text file using the read command and a while loop.

Break and continue

Break and continue are essential in a program that deals with loop statements as they control the flow of the loop statements without any explicit conditions.

Break statement

We use break statements to exit out of the loop without waiting for the condition of the while loop to evaluate to false. This statement can be used within a loop block. This can be used to exit out of an infinite loop with a programmatic condition inside the loop and thus maintain the control of the loop.

For example, we have a script that counts from 1 and forever. But we can programmatically break out of the loop using a break statement inside the body of the loop with a condition.

#!/usr/bin/bash i=1 while : do echo $i if [ $i -eq 20 ]; then echo "This is end of the loop" break if ((i++)) done

From the script and the execution, we can see that we were able to break or exit an infinite loop with a conditional statement and the break statement. Thus the break statement is used to get the control flow of a program/script from inside a while loop to break out of the loop without the loop condition evaluating to false.

Continue statement

We can use the continue statement to do the opposite of the break statement. It will jump to the start of the loop block and iterate again. This can be used for skipping over certain commands for certain conditions and hence allows a change in the flow of the loop.

Читайте также:  Загрузка модуля в линукс

For example, If we have a variable initialized to 1 and we want to display only the numbers divisible by five or in a certain pattern following a condition, we can use continue statements to do just that. This allows iterating over the loop in the desired manner.

#!/usr/bin/bash i=1 while [ $i -lt 30 ]; do ((i++)) if [[ $(( $i % 5 )) -ne 0 ]]; then continue if echo $i done

As we can see the continue statement, jumps to the beginning of the block and starts the execution of the commands by skipping the next commands inside the block. The while loop iterates for only the value of variable i being less than 30, thus the if condition checks if the variable i is divisible by 5, and if it’s not we iterate over again using continue and increment the value of the variable i. The variable i only gets echoed if it’s divisible by 5, thus the if condition is evaluated to false and we do not encounter a continue statement and carry with the normal flow of the loop. This is done to avoid logging of every number and only print the numbers which do not follow a pattern or condition in the if statement or other conditional statements.

Источник

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 

You could not run it in a subshell done < <(find some_directory -type d) , probs wanna use while IFS= read -r dir_name to handle dodge filenames just incase as well.

Why so complicated? find some_directory -type d ! -perm -u+w will give you all non-writable directories in directory

there are few ways: if you only want exit status then just make it like find some_directory -type d ! -perm -u+w | egrep '.*' The return status will be 0 when something is found, and non-zero otherwise. Alternatively you may play with wc -l or if you need to process files then just add -exec <> \; piece to find command

2 Answers 2

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 
 find some_directory -type d|while read dir_name; do [ -w "$dir_name" ] && exit 1 done || exit 1 

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) 

Источник

Оцените статью
Adblock
detector