TecAdmin

Bash Assignment Operators (Shell Scripting)

In bash programming, assignment operators are like tools that let you give values to things. For example, you can tell the computer that “x equals 5” or “name equals tecadmin” . This way, whenever you talk about “x” or “name” later in your code, the computer knows exactly what you mean. It’s like labeling boxes in a storeroom so you know what’s inside each one without opening them.

In this article, we have split the assignment operator into four basic types. Let’s go over each type one by one with an example to make it easier to understand.

1. Standard Assignment Operator

In Bash programming, the standard assignment operator is the = symbol. It is used to assign the value on the right-hand side to the variable on the left-hand side. Make sure there are no spaces around the `=` operator.

Here is an quick example:

In this example, the variable `SHELL` is assigned the value “tecadmin” . If you use `echo $DOAMIN` , the output will be “tecadmin” .

2. Compound Assignment Operators

The compound assignment operators combination of performing some operation and then assign value to variable in a single operation. Basically it reduces line of code in your script and increase performance.

Please note that Bash only supports integer arithmetic natively. If you need to perform operations with floating-point numbers, you will need to use external tools like bc.

3. Read-only Assignment Operator

The readonly operator is used to make a variable’s value constant, which means the value assigned to the variable cannot be changed later. If you try to change the value of a readonly variable, Bash will give an error.

In the above example, PI is declared as a readonly variable and assigned a value of 3.14 . When we try to reassign the value 3.1415 to PI , Bash will give an error message: bash: PI: readonly variable .

4. Local Assignment Operator

The local operator is used within functions to create a local variable – a variable that can only be accessed within the function where it was declared.

In the above example, MY_VAR is declared as a local variable in the my_func function. When we call the function, it prints “I am local” . However, when we try to echo MY_VAR outside of the function, it prints nothing because MY_VAR is not accessible outside my_func .

Assignment operators are used a lot in programming. In shell scripting, they help with saving and changing data. By learning and using these operators well, you can make your scripts work better and faster. This article talked about the basic assignment operator, compound assignment operators, and special ones like readonly and local. Knowing how and when to use each type is important for getting really good for writing Bash scripts.

Related Posts

Shell Scripting Challenge 002! Guess the Output?

Shell Scripting Challenge 002! Guess the Output?

Shell Scripting Challenge - Day 1

Shell Scripting Challenge 001 | What is the output of following Script?

50 bash scripting examples (part-1).

Save my name, email, and website in this browser for the next time I comment.

Type above and press Enter to search. Press Esc to cancel.

LinuxSimply

Home > Bash Scripting Tutorial > Bash Operator > Bash Logical Operators

Bash Logical Operators

Mohammad Shah Miran

Bash logical operators are essential components of shell scripting that enable users to create conditional expressions and make decisions based on the evaluation of conditions. These operators can be combined with various conditions to control the flow of Bash scripts and perform different actions based on specific criteria.

In this article, I will discuss the role of logical operators and their functionality in Bash script. So let’s move on!

Table of Contents

Basics of Logical Operators in Bash

In Bash scripting, logical operators can assess conditions and construct intricate expressions by merging two or more conditions. These operators enable users to determine whether a condition or a set of conditions holds true, granting the ability to manage the script’s execution flow effectively. In the following section, I will give you an overall demonstration of the types of logical operators in bash script.

Types of Logical Operators in Bash

In Bash scripting, logical operators are fundamental for making decisions and controlling the flow of commands based on conditions. They evaluate conditions to be either true or false and make a decision based on the result of the condition. The three primary logical operators are AND , OR , and NOT operators . Let’s have a syntax of each operator below.

  • AND Operator: The AND operator in Bash produces a true outcome solely when both assessed conditions are true. The syntax for the AND operator in Bash scripting is && .
  • OR Operator: The OR operator evaluates to true if at least one of the conditions it connects evaluates to true. The syntax for the OR operator in Bash scripting is || .
  • NOT Operator: The NOT operator in Bash scripting reverses the outcome of a condition. It is denoted by the !  syntax and is used to negate the result of a given condition.

3 Cases of Using Logical Operators in Bash Scripting

In the following section of this article, I will show you the practical cases of bash logical operators to give a sense of their functionality.

Case 01: Combining Conditions With Logical Operators

Combining logical operators can help check multiple conditions simultaneously. Following is an example where two logical AND operators and an echo command are used to display the output of the command.

This Bash script begins by assigning the variables grade to 5 and name to Bob. It then uses a conditional statement within double square brackets ‘[[‘ to check two conditions simultaneously. The first condition, $grade -ge 4  evaluates whether the grade variable is greater than or equal to 4 . The second condition, $name == "Bob" checks if the name variable equals Bob .

The && operator ensures that both conditions must be true for the subsequent command to execute. If both conditions are met, it echoes the message “Student name is Bob and Grade is Greater than 4” to the console.

Combining Conditions with Logical Operators

Case 02: Logical Operators in If-Else Statements

Logical operators can easily be implemented within if-else statement to perform conditional checking. Here’s such an example:

This Bash script starts by checking if the number of command-line arguments provided is less than 3 using the $# variable, which holds the number of arguments . If there are fewer than 3 arguments, it displays a usage message and exits . Then, it assigns the variables age , name , and is_student with the positional parameters $1, $2 and $3 respectively.

Next, it uses an if statement with double square brackets [[ … ]] to check multiple conditions. It verifies whether the age stored in the age variable is greater than 18 , whether the name variable contains the string “John”, and whether the is_student variable is set to true. If all these conditions are met, it prints the message “John is older than 18 and is a student.” Otherwise, it displays “John does not meet all the specified conditions.”

Logical Operators in if-else Statements

Case 03: Combining Multiple Boolean Operators in a Bash Script

Navigate through the script below to combine multiple Boolean (aka logical operators) operators &&, || and ! in Bash:

This Bash script initializes variables for age , name , and student status . It then uses an if statement with logical operators to check if Alice’s age is greater than or equal to 18 , her name is not Bob , and she is either a student or under 30 years old. If all these conditions are met, it prints that Alice is eligible; otherwise, it states that she does not meet the specified conditions.

Combining Multiple Boolean Operators in a Bash Script

5 Practical Examples of Using Logical Operators in Bash Scripting

Previously I showed 3 different scenarios to incorporate the logical operators in bash script. However, the following section will give 5 different examples by using the logical operator.

Example 01: Check if a Number is Within a Specific Range

Logical operators help in creating complex expressions by combining conditions. For instance, the objective of the following Bash script is to assess whether a given numerical value, provided as a command-line argument, falls within the specified range of 10 to 20 .

This Bash script takes a single command-line argument value and checks if it falls within the range of 10 to 20 using an if statement with the && logical operator. If the value is greater than 10 AND less than 20 , it prints “The value is within the range of 10 to 20.” Otherwise, it prints “The value is not within the range of 10 to 20.”

Check if a Number is within a Specific Range

Example 02: Check if a User is Either “root” or “admin” Using Boolean Operators

The OR operator is used to check if any of the condition is true within a conditional statement. For example, here’s a Bash script that determines whether a user , represented by the variable username , is either root or admin and ascertain if the user has administrative privileges on the system.

This Bash script begins by capturing a username provided as an argument when running the script. It proceeds to check two conditions using the if statement. First, it examines whether the effective user ID ( UID ) of the user executing the script is equal to 0 , which signifies the root user .

Second, it employs the sudo command to evaluate whether the specified username has sudo privileges. The grep -q part in this condition silences any output and checks if the pattern (ALL : ALL) exists in the sudo configuration, indicating sudo privileges. If either condition is true, the script prints a message declaring that the user possesses sudo privileges and is thus either the root user or an admin user. Conversely, if neither condition is met, it communicates that the username is neither the root user nor has sudo privileges.

 Check if a User is Either “root” or “admin” Using Boolean Operators

Example 03: Invert a Condition Using the “NOT” Operator

The NOT (!) operator reverses the condition within an if statement in Bash. Check out the following script to see the example of condition inversion:

This Bash script begins by defining a variable named file_to_check and assigns it the value test_file.txt . It then uses an if statement to check if the file specified by file_to_check exists in the current directory, utilizing the -e test operator within double square brackets. If the file does not exist, it outputs a message indicating that the file is not present. Conversely, if the file exists, it outputs a message confirming its existence.

Invert a Condition Using the NOT Operator-2

Example 04: Using of “NOT” and “AND” Logical Operators in a Single Line

To combine the NOT and AND operators in a single line, go through the script below:

The given bash code starts by prompting the user to enter their age and whether they have any voting disqualifications. It uses the read command to capture these inputs. Then, it uses an if statement to check if the user’s age is greater than or equal to 18 and if their response to disqualifications is not yes. If both conditions are met, it prints “Congratulations! You are eligible to vote.” Otherwise, it prints “Sorry, you are not eligible to vote at the moment.”

Using of OR and NOT Operator in a Single Line

Example 05: Using of “OR” and “NOT” Operator in a Single Line

Navigate through the following script to use the NOT and OR operators together in a single line:

The code begins by printing a message asking the user to provide their correct username and password for a greeting. The correct username and password are defined as “miran” and 1234 in the script. The script uses the read to prompt the user to enter their username and password . The -s flag with read is used for the password input to keep it hidden as the user types.

It then uses an if statement to check if the entered username and password match the correct ones. If either the username or password is incorrect, it prints “Login failed. Invalid username or password.” Otherwise, if both are correct, it prints “Login successful! Welcome, [username].”

Using of NOT and AND Logical Operators in a Single Line

In conclusion, Logical operators in bash scripting can play a vital role in assigning multiple conditions and making decisions based on them. In this article, I have demonstrated some different examples of logical operators in bash to convey its functionality. If you have any questions or queries related to this, feel free to comment below. I will get back to you soon. Till then, Happy Coding!

People Also Ask

What are logical operators in bash.

Logical operators in Bash include && ( AND ), || ( OR ), and ! ( NOT ). They are used to perform logical comparisons and control the flow of commands based on conditions.

What is the += operator in Bash?

In Bash, the += operator is a compound assignment operator that allows you to add ( concatenate ) a string or value to the end of an existing variable’s value. It’s commonly used for building or modifying strings dynamically in scripts.

What is binary operator in Bash?

A binary operator in Bash is an operator that works on two operands or values. It requires two values to perform an operation, such as addition , subtraction , comparison , or logical operations . Examples of binary operators in Bash include + for addition , – for subtraction , == for equality comparison , and && for logical AND operations .

What is the use of && in Bash?

In Bash, && is a logical operator used to execute the command on its right only if the command on its left succeeds (returns a zero exit status).

Related Articles

  • Boolean Variables “True False” and Logical Operators in Bash
  • Usage of Logical AND (&&) Operator in Bash Scripting
  • Usage of OR Operator in Bash Scripting [2 Cases]
  • Usages of NOT (!) Operator in Bash Scripting [4 Examples]

<< Go Back to Bash Operator | Bash Scripting Tutorial

Mohammad Shah Miran

Mohammad Shah Miran

Hey, I'm Mohammad Shah Miran, previously worked as a VBA and Excel Content Developer at SOFTEKO, and for now working as a Linux Content Developer Executive in LinuxSimply Project. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). As a part of my job, i communicate with Linux operating system, without letting the GUI to intervene and try to pass it to our audience.

Leave a Comment Cancel reply

Save my name, email, and website in this browser for the next time I comment.

linuxsimply white logo

Get In Touch!

card

Legal Corner

dmca

Copyright © 2024 LinuxSimply | All Rights Reserved.

Learn Scripting

Coding Knowledge Unveiled: Empower Yourself

Mastering Operators in Shell Scripting: A Comprehensive Guide

Shell scripting is a powerful tool for automating tasks and performing various operations on Unix-like operating systems. Operators play a fundamental role in shell scripts, allowing you to manipulate data, perform calculations, and make decisions. In this blog, we’ll delve into the world of operators in shell scripting, exploring their types, usage, and real-world applications.

Operators in Shell Scripting

Operators in shell scripting are symbols or special keywords that perform operations on variables, constants, and values. They allow you to work with data, make comparisons, and control the flow of your scripts. Shell scripting supports several types of operators:

1. Arithmetic Operators

Arithmetic operators are used to perform mathematical calculations in shell scripts. They include:

  • Addition (+): Adds two values.
  • Subtraction (-): Subtracts the second value from the first.
  • Multiplication (*): Multiplies two values.
  • Division (/): Divides the first value by the second.
  • Modulus (%): Computes the remainder of the division.
  • Exponentiation ( or ^):** Raises the first value to the power of the second (not available in all shells).

Here’s an example of using arithmetic operators in a shell script:

2. Comparison Operators

Comparison operators are used to compare values or expressions in shell scripts. They return a Boolean result (either true or false) based on the comparison. Common comparison operators include:

  • Equal to (==): Checks if two values are equal.
  • Not equal to (!=): Checks if two values are not equal.
  • Greater than (>): Checks if the first value is greater than the second.
  • Less than (<): Checks if the first value is less than the second.
  • Greater than or equal to (>=): Checks if the first value is greater than or equal to the second.
  • Less than or equal to (<=): Checks if the first value is less than or equal to the second.

Here’s an example of using comparison operators in a shell script:

3. Logical Operators

Logical operators are used to perform logical operations in shell scripts, especially within conditional statements. They include:

  • AND (&&): Returns true if both operands are true.
  • OR (||): Returns true if at least one operand is true.
  • NOT (!): Inverts the Boolean value of the operand.

Here’s an example of using logical operators in a shell script:

4. Assignment Operators

Assignment operators are used to assign values to variables in shell scripts. The basic assignment operator is = . However, there are also compound assignment operators that combine an operation with assignment, such as += , -= , *= , and /= .

Here’s an example of using assignment operators in a shell script:

5. String Operators

String operators are used for string manipulation in shell scripts. They include:

  • Concatenation (+=): Combines two strings.
  • Equality (==): Checks if two strings are equal.
  • Inequality (!=): Checks if two strings are not equal.
  • Length (strlen): Returns the length of a string.

Here’s an example of using string operators in a shell script:

Real-World Applications

Operators are essential in shell scripting and have numerous real-world applications:

  • Data Processing: Operators are used to manipulate data, perform calculations, and format output.
  • Conditionals: Comparison and logical operators enable you to create conditional statements for decision-making in scripts.
  • Looping: Operators play a crucial role in controlling loops, allowing you to set conditions for loop termination.
  • String Manipulation: String operators help in tasks like concatenating, splitting, and checking strings.
  • File Operations: Operators are used in shell scripts for file operations, such as checking file existence, permissions, and modification dates.
  • Script Automation: Operators facilitate automation by enabling scripts to make decisions and perform actions based on conditions.

Operators are the building blocks of shell scripting, enabling you to perform a wide range of tasks efficiently and effectively. By understanding and mastering the various types of operators, you can write more powerful and flexible shell scripts to automate tasks, manipulate data, and make intelligent decisions. Whether you’re a system administrator, developer, or data analyst, a solid grasp of shell scripting operators is a valuable skill in the world of Unix-like operating systems.

Leave a Reply Cancel reply

You must be logged in to post a comment.

How-To Geek

How to work with variables in bash.

Want to take your Linux command-line skills to the next level? Here's everything you need to know to start working with variables.

Hannah Stryker / How-To Geek

Quick Links

What is a variable in bash, examples of bash variables, how to use bash variables in scripts, how to use command line parameters in scripts, working with special variables, environment variables, how to export variables, how to quote variables, echo is your friend, key takeaways.

  • Variables are named symbols representing strings or numeric values. They are treated as their value when used in commands and expressions.
  • Variable names should be descriptive and cannot start with a number or contain spaces. They can start with an underscore and can have alphanumeric characters.
  • Variables can be used to store and reference values. The value of a variable can be changed, and it can be referenced by using the dollar sign $ before the variable name.

Variables are vital if you want to write scripts and understand what that code you're about to cut and paste from the web will do to your Linux computer. We'll get you started!

Variables are named symbols that represent either a string or numeric value. When you use them in commands and expressions, they are treated as if you had typed the value they hold instead of the name of the variable.

To create a variable, you just provide a name and value for it. Your variable names should be descriptive and remind you of the value they hold. A variable name cannot start with a number, nor can it contain spaces. It can, however, start with an underscore. Apart from that, you can use any mix of upper- and lowercase alphanumeric characters.

Here, we'll create five variables. The format is to type the name, the equals sign = , and the value. Note there isn't a space before or after the equals sign. Giving a variable a value is often referred to as assigning a value to the variable.

We'll create four string variables and one numeric variable,

my_name=Dave

my_boost=Linux

his_boost=Spinach

this_year=2019

To see the value held in a variable, use the echo command. You must precede the variable name with a dollar sign $ whenever you reference the value it contains, as shown below:

echo $my_name

echo $my_boost

echo $this_year

Let's use all of our variables at once:

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

The values of the variables replace their names. You can also change the values of variables. To assign a new value to the variable, my_boost , you just repeat what you did when you assigned its first value, like so:

my_boost=Tequila

If you re-run the previous command, you now get a different result:

So, you can use the same command that references the same variables and get different results if you change the values held in the variables.

We'll talk about quoting variables later. For now, here are some things to remember:

  • A variable in single quotes ' is treated as a literal string, and not as a variable.
  • Variables in quotation marks " are treated as variables.
  • To get the value held in a variable, you have to provide the dollar sign $ .
  • A variable without the dollar sign $ only provides the name of the variable.

You can also create a variable that takes its value from an existing variable or number of variables. The following command defines a new variable called drink_of_the_Year, and assigns it the combined values of the my_boost and this_year variables:

drink_of-the_Year="$my_boost $this_year"

echo drink_of_the-Year

Scripts would be completely hamstrung without variables. Variables provide the flexibility that makes a script a general, rather than a specific, solution. To illustrate the difference, here's a script that counts the files in the /dev directory.

Type this into a text file, and then save it as fcnt.sh (for "file count"):

#!/bin/bashfolder_to_count=/devfile_count=$(ls $folder_to_count | wc -l)echo $file_count files in $folder_to_count

Before you can run the script, you have to make it executable, as shown below:

chmod +x fcnt.sh

Type the following to run the script:

This prints the number of files in the /dev directory. Here's how it works:

  • A variable called folder_to_count is defined, and it's set to hold the string "/dev."
  • Another variable, called file_count , is defined. This variable takes its value from a command substitution. This is the command phrase between the parentheses $( ) . Note there's a dollar sign $ before the first parenthesis. This construct $( ) evaluates the commands within the parentheses, and then returns their final value. In this example, that value is assigned to the file_count variable. As far as the file_count variable is concerned, it's passed a value to hold; it isn't concerned with how the value was obtained.
  • The command evaluated in the command substitution performs an ls file listing on the directory in the folder_to_count variable, which has been set to "/dev." So, the script executes the command "ls /dev."
  • The output from this command is piped into the wc command. The -l (line count) option causes wc to count the number of lines in the output from the ls command. As each file is listed on a separate line, this is the count of files and subdirectories in the "/dev" directory. This value is assigned to the file_count variable.
  • The final line uses echo to output the result.

But this only works for the "/dev" directory. How can we make the script work with any directory? All it takes is one small change.

Many commands, such as ls and wc , take command line parameters. These provide information to the command, so it knows what you want it to do. If you want ls to work on your home directory and also to show hidden files , you can use the following command, where the tilde ~ and the -a (all) option are command line parameters:

Our scripts can accept command line parameters. They're referenced as $1 for the first parameter, $2 as the second, and so on, up to $9 for the ninth parameter. (Actually, there's a $0 , as well, but that's reserved to always hold the script.)

You can reference command line parameters in a script just as you would regular variables. Let's modify our script, as shown below, and save it with the new name fcnt2.sh :

#!/bin/bashfolder_to_count=$1file_count=$(ls $folder_to_count | wc -l)echo $file_count files in $folder_to_count

This time, the folder_to_count variable is assigned the value of the first command line parameter, $1 .

The rest of the script works exactly as it did before. Rather than a specific solution, your script is now a general one. You can use it on any directory because it's not hardcoded to work only with "/dev."

Here's how you make the script executable:

chmod +x fcnt2.sh

Now, try it with a few directories. You can do "/dev" first to make sure you get the same result as before. Type the following:

./fnct2.sh /dev

./fnct2.sh /etc

./fnct2.sh /bin

You get the same result (207 files) as before for the "/dev" directory. This is encouraging, and you get directory-specific results for each of the other command line parameters.

To shorten the script, you could dispense with the variable, folder_to_count , altogether, and just reference $1 throughout, as follows:

#!/bin/bash file_count=$(ls $1 wc -l) echo $file_count files in $1

We mentioned $0 , which is always set to the filename of the script. This allows you to use the script to do things like print its name out correctly, even if it's renamed. This is useful in logging situations, in which you want to know the name of the process that added an entry.

The following are the other special preset variables:

  • $# : How many command line parameters were passed to the script.
  • $@ : All the command line parameters passed to the script.
  • $? : The exit status of the last process to run.
  • $$ : The Process ID (PID) of the current script.
  • $USER : The username of the user executing the script.
  • $HOSTNAME : The hostname of the computer running the script.
  • $SECONDS : The number of seconds the script has been running for.
  • $RANDOM : Returns a random number.
  • $LINENO : Returns the current line number of the script.

You want to see all of them in one script, don't you? You can! Save the following as a text file called, special.sh :

#!/bin/bashecho "There were $# command line parameters"echo "They are: $@"echo "Parameter 1 is: $1"echo "The script is called: $0"# any old process so that we can report on the exit statuspwdecho "pwd returned $?"echo "This script has Process ID $$"echo "The script was started by $USER"echo "It is running on $HOSTNAME"sleep 3echo "It has been running for $SECONDS seconds"echo "Random number: $RANDOM"echo "This is line number $LINENO of the script"

Type the following to make it executable:

chmod +x special.sh

Now, you can run it with a bunch of different command line parameters, as shown below.

Bash uses environment variables to define and record the properties of the environment it creates when it launches. These hold information Bash can readily access, such as your username, locale, the number of commands your history file can hold, your default editor, and lots more.

To see the active environment variables in your Bash session, use this command:

If you scroll through the list, you might find some that would be useful to reference in your scripts.

When a script runs, it's in its own process, and the variables it uses cannot be seen outside of that process. If you want to share a variable with another script that your script launches, you have to export that variable. We'll show you how to this with two scripts.

First, save the following with the filename script_one.sh :

#!/bin/bashfirst_var=alphasecond_var=bravo# check their valuesecho "$0: first_var=$first_var, second_var=$second_var"export first_varexport second_var./script_two.sh# check their values againecho "$0: first_var=$first_var, second_var=$second_var"

This creates two variables, first_var and second_var , and it assigns some values. It prints these to the terminal window, exports the variables, and calls script_two.sh . When script_two.sh terminates, and process flow returns to this script, it again prints the variables to the terminal window. Then, you can see if they changed.

The second script we'll use is script_two.sh . This is the script that script_one.sh calls. Type the following:

#!/bin/bash# check their valuesecho "$0: first_var=$first_var, second_var=$second_var"# set new valuesfirst_var=charliesecond_var=delta# check their values againecho "$0: first_var=$first_var, second_var=$second_var"

This second script prints the values of the two variables, assigns new values to them, and then prints them again.

To run these scripts, you have to type the following to make them executable:

chmod +x script_one.shchmod +x script_two.sh

And now, type the following to launch script_one.sh :

./script_one.sh

This is what the output tells us:

  • script_one.sh prints the values of the variables, which are alpha and bravo.
  • script_two.sh prints the values of the variables (alpha and bravo) as it received them.
  • script_two.sh changes them to charlie and delta.
  • script_one.sh prints the values of the variables, which are still alpha and bravo.

What happens in the second script, stays in the second script. It's like copies of the variables are sent to the second script, but they're discarded when that script exits. The original variables in the first script aren't altered by anything that happens to the copies of them in the second.

You might have noticed that when scripts reference variables, they're in quotation marks " . This allows variables to be referenced correctly, so their values are used when the line is executed in the script.

If the value you assign to a variable includes spaces, they must be in quotation marks when you assign them to the variable. This is because, by default, Bash uses a space as a delimiter.

Here's an example:

site_name=How-To Geek

Bash sees the space before "Geek" as an indication that a new command is starting. It reports that there is no such command, and abandons the line. echo shows us that the site_name variable holds nothing — not even the "How-To" text.

Try that again with quotation marks around the value, as shown below:

site_name="How-To Geek"

This time, it's recognized as a single value and assigned correctly to the site_name variable.

It can take some time to get used to command substitution, quoting variables, and remembering when to include the dollar sign.

Before you hit Enter and execute a line of Bash commands, try it with echo in front of it. This way, you can make sure what's going to happen is what you want. You can also catch any mistakes you might have made in the syntax.

Bash documentation

Notes while learning bash, table of contents, introduction.

  • First program

Local variables

Environment variables, positional parameters, curli brace expansion, parenthesis command substitution, single vs double square braces, double and single quotes, array declaration, array expansion, array slice, adding elements into an array, deleting elements from an array, lists of commands.

  • String Operations

Primary and combining expressions

Using an if statement, using a case statement, select loop, loop control, example four instance.

Bash is a Unix shell written by [Brian Fox][] for the GNU Project as a free software replacement for the Bourne shell . It was released in 1989 and has been distributed as the Linux and OS X default shell for a long time. [Brian Fox]: https://en.wikipedia.org/wiki/Brian_Fox_(computer_programmer)

Shells Basic

Shell scripts are just a text file that consist of list of commands which are executed by shell interpreter sequentially. For example - Get name of user and say hello

First Program

Put the below five line line in script.sh

add execute permission

Note that the first line in the script must indicate which program it should use to run the file, like so:

Or if you prefer to use sh instead of bash , change #!/bin/bash to #!/bin/sh . This #! character sequence is known as the shebang . Now you can run the script like this:

A handy trick we used above is using echo to print text to the terminal screen.

Another way to use the shebang line is as follows:

The advantage of this shebang line is it will search for the program (in this case bash ) based on the PATH environment variable.

Every command returns an exit code ( return status or exit status ). A successful command always returns 0 (zero-code), and a command that has failed returns a non-zero value (error code). Failure codes must be positive integers between 1 and 255.

When a program terminates, the shell assigns its exit code to the $? environment variable. The $? variable is how we usually test whether a script has succeeded or not in its execution.

Scripts may contain comments . Comments are special statements ignored by the shell interpreter. They begin with a # symbol and continue on to the end of the line.

For example:

Tip : Use comments to explain what your script does and why .

Like in most programming languages, you can also create variables in bash.

Bash knows no data types. Variables can contain only numbers or a string of one or more characters. There are three kinds of variables you can create: local variables, environment variables and variables as positional arguments .

Local variables are variables that exist only within a single script.

A local variable can be declared using = sign (as a rule, there should not be any spaces between a variable’s name, = and its value) and its value can be retrieved using the $ sign. For example:

We can also declare a variable local to a single function using the local keyword. Doing so causes the variable to disappear when the function exits.

Environment variables are variables accessible to any program or script running in current shell session. They are created just like local variables, but using the keyword export instead.

There are a lot of global variables in bash. You will meet these variables fairly often, so here is a quick lookup table with the most practical ones:

Follow this link to see an extended list of environment variables in Bash.

Positional parameters are variables allocated when a function is evaluated and are given positionally. The following table lists positional parameter variables and other special variables and their meanings when you are inside a function.

In the example below, the positional parameters will be $0='./script.sh' , $1='foo' and $2='bar' :

Variables may also have default values. We can define as such using the following syntax:

Shell expansions

Expansions are performed on the command line after it has been split into tokens . In other words, these expansions are a mechanism to calculate arithmetical operations, to save results of commands’ executions and so on.

If you are interested, you can read more about shell expansions .

{…} Brace expansion allows us to generate arbitrary strings. It’s similar to filename expansion . For example:

Also brace expansions may be used for creating ranges, which are iterated over in loops.

{…} Braces are also used to execute a sequence of commands in the current shell context . For example:

${…} means return the value of the shell variable named in the braces. Braces ({}) are used to unambiguously identify variables

(…) Means run the commands listed in the parens in a subshell . For Example:

$(…) - Command substitution allow us to evaluate a command and substitute its value into another command or variable assignment. Command substitution is performed when a command is enclosed by `` or $() . For example, we can use it as follows:

((…)) - means perform arithmetic, possibly changing the values of shell variables, but don’t return its result. For Example:

$((…)) Double-Parentheses Construct - Similar to the let command, the (( … )) construct permits arithmetic expansion and evaluation. In its simplest form, a=$(( 5 + 3 )) would set a to 5 + 3, or 8. However, this double-parentheses construct is also a mechanism for allowing C-style manipulation of variables in Bash, for example, (( var++ )).

In bash we are free to do any arithmetical operations. But the expression must enclosed by $(( )) The format for arithmetic expansions is:

Within arithmetic expansions, variables should generally be used without a $ prefix:

Double parenthesis is also used for making c-sytle loops like

[ is POSIX regular command with a weird name. [[ is a Bash extension that makes parsing magical. It also allows uses of <, &&, || and () and string pattern matching like = and =~.

[[ allows to to use comparision operators ==, !=, <, and > with anything. With [ it can be used for string only.

[[ is bash’s improvemen so no unnecessary double quote is needed.

There is an important difference between double and single quotes. Inside double quotes variables or command substitutions are expanded. Inside single quotes they are not. For example:

Take care to expand local variables and environment variables within quotes if they could contain whitespace. As an innocuous example, consider using echo to print some user input:

The first echo is invoked with 5 separate arguments — $INPUT is split into separate words, echo prints a single space character between each. In the second case, echo is invoked with a single argument (the entire $INPUT value, including whitespace).

Now consider a more serious example:

While the issue in this example could be resolved by renaming FILE to Favorite-Things.txt , consider input coming from an environment variable, a positional parameter, or the output of another command ( find , cat , etc). If the input might contain whitespace, take care to wrap the expansion in quotes.

Like in other programming languages, an array in bash is a variable that allows you to refer to multiple values. In bash, arrays are also zero-based, that is, the first element in an array has index 0.

When dealing with arrays, we should be aware of the special environment variable IFS . IFS , or Input Field Separator , is the character that separates elements in an array. The default value is an empty space IFS=' ' .

In bash you create an array by simply assigning a value to an index in the array variable:

Array variables can also be created using compound assignments such as:

Individual array elements are expanded similar to other variables:

The entire array can be expanded by using * or @ in place of the numeric index:

There is an important (and subtle) difference between the two lines above: consider an array element containing whitespace:

We want to print each element of the array on a separate line, so we try to use the printf builtin:

Why were Desert and fig printed on separate lines? Let’s try to use quoting:

Now everything is on one line — that’s not what we wanted! Here’s where ${fruits[@]} comes into play:

Within double quotes, ${fruits[@]} expands to a separate argument for each element in the array; whitespace in the array elements is preserved.

Besides, we can extract a slice of array using the slice operators:

In the example above, ${fruits[@]} expands to the entire contents of the array, and :0:2 extracts the slice of length 2, that starts at index 0.

Adding elements into an array is quite simple too. Compound assignments are specially useful in this case. We can use them like this:

The example above, ${fruits[@]} expands to the entire contents of the array and substitutes it into the compound assignment, then assigns the new value into the fruits array mutating its original value.

To delete an element from an array, use the unset command:

Streams, pipes and lists

Bash has powerful tools for working with other programs and their outputs. Using streams we can send the output of a program into another program or file and thereby write logs or whatever we want.

Pipes give us opportunity to create conveyors and control the execution of commands.

It is paramount we understand how to use this powerful and sophisticated tool.

Bash receives input and sends output as sequences or streams of characters. These streams may be redirected into files or one into another.

There are three descriptors:

Redirection makes it possible to control where the output of a command goes to, and where the input of a command comes from. For redirecting streams these operators are used:

Here are few examples of using redirections:

We could redirect standard streams not only in files, but also to other programs. Pipes let us use the output of a program as the input of another.

In the example below, command1 sends its output to command2 , which then passes it on to the input of command3 :

Constructions like this are called pipelines .

In practice, this can be used to process data through several programs. For example, here the output of ls -l is sent to the grep program, which prints only files with a .md extension, and this output is finally sent to the less program:

The exit status of a pipeline is normally the exit status of the last command in the pipeline. The shell will not return a status until all the commands in the pipeline have completed. If you want your pipelines to be considered a failure if any of the commands in the pipeline fail, you should set the pipefail option with:

A list of commands is a sequence of one or more pipelines separated by ; , & , && or || operator.

If a command is terminated by the control operator & , the shell executes the command asynchronously in a subshell. In other words, this command will be executed in the background.

Commands separated by a ; are executed sequentially: one after another. The shell waits for the finish of each command.

Lists separated by && and || are called AND and OR lists, respectively.

The AND-list looks like this:

Example : Run a command with root if it is not running as root

The OR-list has the form:

The return code of an AND or OR list is the exit status of the last executed command.

String operations

Conditional statements.

Like in other languages, Bash conditionals let us decide to perform an action or not. The result is determined by evaluating an expression, which should be enclosed in [[ ]] .

Conditional expression may contain && and || operators, which are AND and OR accordingly. Besides this, there many other handy expressions .

There are two different conditional statements: if statement and case statement.

Expressions enclosed inside [[ ]] (or [ ] for sh ) are called test commands or primaries . These expressions help us to indicate results of a conditional. In the tables below, we are using [ ] , because it works for sh too. Here is an answer about the difference between double and single square brackets in bash .

Working with the file system:

Working with strings:

Arithmetic binary operators:

Conditions may be combined using these combining expressions:

Sure, there are more useful primaries and you can easily find them in the Bash man pages .

if statements work the same as in other programming languages. If the expression within the braces is true, the code between then and fi is executed. fi indicates the end of the conditionally executed code.

For example :

Sometimes if..else statements are not enough to do what we want to do. In this case we shouldn’t forget about the existence of if..elif..else statements, which always come in handy.

Look at the example below:

If you are confronted with a couple of different possible actions to take, then using a case statement may be more useful than nested if statements. For more complex conditions use case like below:

Example : Take argument in bash and assign it to variable using case (simulation of perl optget)

Each case is an expression matching a pattern. The | sign is used for separating multiple patterns, and the ) operator terminates a pattern list. The commands for the first match are executed. * is the pattern for anything else that doesn’t match the defined patterns. Each block of commands should be divided with the ;; operator.

Here we won’t be surprised. As in any programming language, a loop in bash is a block of code that iterates as long as the control conditional is true.

There are four types of loops in Bash: for , while , until and select .

The for is very similar to its sibling in C. It looks like this:

During each pass through the loop, arg takes on the value from elem1 to elemN . Values may also be wildcards or brace expansions .

Also, we can write for loop in one line, but in this case there needs to be a semicolon before do , like below:

By the way, if for..in..do seems a little bit weird to you, you can also write for in C-like style such as:

for is handy when we want to do the same operation over each file in a directory. For example, if we need to move all .bash files into the script folder and then give them execute permissions, our script would look like this:

Omitting the in [list] part of a for loop causes the loop to operate on $@ – the positional parameters.

The while loop tests a condition and loops over a sequence of commands so long as that condition is true . A condition is nothing more than a primary as used in if..then conditions. So a while loop looks like this:

Just like in the case of the for loop, if we want to write do and condition in the same line, then we must use a semicolon before do .

A working example might look like this:

The until loop is the exact opposite of the while loop. Like a while it checks a test condition, but it keeps looping as long as this condition is false :

The select loop helps us to organize a user menu. It has almost the same syntax as the for loop:

The select prints all elem1..elemN on the screen with their sequence numbers, after that it prompts the user. Usually it looks like $? ( PS3 variable). The answer will be saved in answer . If answer is the number between 1..N , then statements will execute and select will go to the next iteration — that’s because we should use the break statement.

This example, asks the user what package manager {s,he} would like to use. Then, it will ask what package we want to install and finally proceed to install it.

If we run this, we will get:

There are situations when we need to stop a loop before its normal ending or step over an iteration. In these cases, we can use the shell built-in break and continue statements. Both of these work with every kind of loop.

The break statement is used to exit the current loop before its ending. We have already met with it.

The continue statement steps over one iteration. We can use it as such:

If we run the example above, it will print all odd numbers from 0 through 9.

In scripts we have the ability to define and call functions. As in any programming language, functions in bash are chunks of code, but there are differences.

In bash, functions are a sequence of commands grouped under a single name, that is the name of the function. Calling a function is the same as calling any other program, you just write the name and the function will be invoked .

We can declare our own function this way:

We must declare functions before we can invoke them.

Functions can take on arguments and return a result — exit code. Arguments, within functions, are treated in the same manner as arguments given to the script in non-interactive mode — using positional parameters . A result code can be returned using the return command.

Below is a function that takes a name and returns 0 , indicating successful execution.

We already discussed exit codes . The return command without any arguments returns the exit code of the last executed command. Above, return 0 will return a successful exit code. 0 .

The shell gives us tools for debugging scripts. If we want to run a script in debug mode, we use a special option in our script’s shebang:

These options are settings that change shell behavior. The following table is a list of options which might be useful to you:

For example, we have script with -x option such as:

This will print the value of the variables to stdout along with other useful information:

Sometimes we need to debug a part of a script. In this case using the set command is convenient. This command can enable and disable options. Options are turned on using - and turned off using + :

Multithreading in bash

Mutlit-threadhing in bash is achieved by pushing command to background. For example.

Spawn a child process and wait for it and kill if it doesn’t die after specific time.

Spawn a child process and get the exit status as well

Commands and Example

  • bash-handbook
  • Advance bash scripting Guide
  • Bash quick reference

Bash Shell Scripting/Shell Arithmetic

Arithmetic expressions in Bash are closely modeled on those in C, so they are very similar to those in other C-derived languages, such as C++, Java, Perl, JavaScript, C#, and PHP. One major difference is that Bash only supports integer arithmetic (whole numbers), not floating-point arithmetic (decimals and fractions); something like 3 + 4 means what you'd expect (7), but something like 3.4 + 4.5 is a syntax error. Something like 13 / 5 is fine, but performs integer division, so evaluates to 2 rather than to 2.6.

  • 1 Arithmetic expansion
  • 2 expr (deprecated)
  • 3 Numeric operators
  • 4 Referring to variables
  • 5 Assigning to variables
  • 6 Arithmetic expressions as their own commands
  • 7 The comma operator
  • 8 Comparison, Boolean, and conditional operators
  • 9 Arithmetic for-loops
  • 10 Bitwise operators
  • 11 Integer literals
  • 12 Integer variables
  • 13 Non-integer arithmetic

Arithmetic expansion

Perhaps the most common way to use arithmetic expressions is in arithmetic expansion , where the result of an arithmetic expression is used as an argument to a command. Arithmetic expansion is denoted $(( … )) . For example, this command:

prints 19 .

expr (deprecated)

Another way to use arithmetic expressions is using the Unix program "expr", which was popular before Bash supported math. [1] Similar to Arithmetic expansion, this command:

prints 19 . Note that using "expr" requires an escape character "\" before the multiplication operator "*" and parentheses. Further note the spaces between each operator symbol, including the parentheses.

Numeric operators

In addition to the familiar notations + (addition) and - (subtraction), arithmetic expressions also support * (multiplication), / (integer division, described above), % (modulo division, the "remainder" operation; for example, 11 divided by 5 is 2 remainder 1, so 11 % 5 is 1 ), and ** ("exponentiation", i.e. involution; for example, 2 4  = 16, so 2 ** 4 is 16 ).

The operators + and - , in addition to their "binary" (two-operand) senses of "addition" and "subtraction", have "unary" (one-operand) senses of "positive" and "negative". Unary + has basically no effect; unary - inverts the sign of its operand. For example, -(3*4) evaluates to -12 , and -(-(3*4)) evaluates to 12 .

Referring to variables

Inside an arithmetic expression, shell variables can be referred to directly, without using variable expansion (that is, without the dollar sign $ ). For example, this:

prints 35 . (Note that i is evaluated first, producing 5, and then it's multiplied by 7. If we had written $i rather than i , mere string substitution would have been performed; 7 * 2+3 equals 14 + 3, that is, 17 — probably not what we want.)

The previous example shown using "expr":

prints 35 .

Assigning to variables

Shell variables can also be assigned to within an arithmetic expression. The notation for this is similar to that of regular variable assignment, but is much more flexible. For example, the previous example could be rewritten like this:

except that this sets $i to 5 rather than to 2+3 . Note that, although arithmetic expansion looks a bit like command substitution, it is not executed in a subshell; this command actually sets $i to 5 , and later commands can use the new value. (The parentheses inside the arithmetic expression are just the normal mathematical use of parentheses to control the order of operations.)

In addition to the simple assignment operator = , Bash also supports compound operators such as += , -= , *= , /= , and %= , which perform an operation followed by an assignment. For example, (( i *= 2 + 3 )) is equivalent to (( i = i * (2 + 3) )) . In each case, the expression as a whole evaluates to the new value of the variable; for example, if $i is 4 , then (( j = i *= 3 )) sets both $i and $j to 12 .

Lastly, Bash supports increment and decrement operators. The increment operator ++ increases a variable's value by 1; if it precedes the variable-name (as the "pre-increment" operator), then the expression evaluates to the variable's new value, and if it follows the variable-name (as the "post-increment" operator), then the expression evaluates to the variable's old value. For example, if $i is 4 , then (( j = ++i )) sets both $i and $j to 5 , while (( j = i++ )) sets $i to 5 and $j to 4 . The decrement operator -- is exactly the same, except that it decreases the variable's value by 1. Pre-decrement and post-decrement are completely analogous to pre-increment and post-increment.

Arithmetic expressions as their own commands

A command can consist entirely of an arithmetic expression, using either of the following syntaxes:

Either of these commands will set $i to 5 . Both styles of command return an exit status of zero ("successful" or "true") if the expression evaluates to a non-zero value, and an exit status of one ("failure" or "false") if the expression evaluates to zero. For example, this:

will print this:

The reason for this counterintuitive behavior is that in C, zero means "false" and non-zero values (especially one) mean "true". Bash maintains that legacy inside arithmetic expressions, then translates it into the usual Bash convention at the end.

The comma operator

Arithmetic expressions can contain multiple sub-expressions separated by commas , . The result of the last sub-expression becomes the overall value of the full expression. For example, this:

sets $i to 2 , sets $j to 4 , and prints 8 .

The let built-in actually supports multiple expressions directly without needing a comma; therefore, the following three commands are equivalent:

Comparison, Boolean, and conditional operators

Arithmetic expressions support the integer comparison operators < , > , <= (meaning ≤), >= (meaning ≥), == (meaning =), and != (meaning ≠). Each evaluates to 1 for "true" or 0 for "false".

They also support the Boolean operators && ("and"), which evaluates to 0 if either of its operands is zero, and to 1 otherwise; || ("or"), which evaluates to 1 if either of its operands is nonzero, and to 0 otherwise; and ! ("not"), which evaluates to 1 if its operand is zero, and to 0 otherwise. Aside from their use of zero to mean "false" and nonzero values to mean "true", these are just like the operators && , || , and ! that we've seen outside arithmetic expressions. Like those operators, these are "short-cutting" operators that do not evaluate their second argument if their first argument is enough to determine a result. For example, (( ( i = 0 ) && ( j = 2 ) )) will not evaluate the ( j = 2 ) part, and therefore will not set $j to 2 , because the left operand of && is zero ("false").

And they support the conditional operator b  ? e1  : e2 . This operator evaluates e1 , and returns its result, if b is nonzero; otherwise, it evaluates e2 and returns its result.

These operators can be combined in complex ways:

Arithmetic for-loops

Above, we saw one style of for-loop, that looked like this:

Bash also supports another style, modeled on the for-loops of C and related languages, using shell arithmetic:

This for-loop uses three separate arithmetic expressions, separated by semicolons ; (and not commas , — these are completely separate expressions, not just sub-expressions). The first is an initialization expression, run before the loop begins. The second is a test expression; it is evaluated before every potential loop iteration (including the first), and if it evaluates to zero ("false"), then the loop exits. The third is a counting expression; it is evaluated at the end of each loop iteration. In other words, this for-loop is exactly equivalent to this while-loop:

but, once you get used to the syntax, it makes it more clear what is going on.

Bitwise operators

In addition to regular arithmetic and Boolean operators, Bash also offers "bitwise" operators, meaning operators that operate on integers qua bit-strings rather than qua integers. If you are not already familiar with this concept, you can safely ignore these.

Just as in C, the bitwise operators are & (bitwise "and"), | (bitwise "or"), ^ (bitwise "exclusive or"), ~ (bitwise "not"), << (bitwise left-shift), and >> (bitwise right-shift), as well as &= and |= and ^= (which include assignment, just like += ).

Integer literals

An integer constant is expressed as an integer literal . We have already seen many of these; 34 , for example, is an integer literal denoting the number 34. All of our examples have been decimal (base ten) integer literals, which is the default; but in fact, literals may be expressed in any base in the range 2–64, using the notation base # value (with the base itself being expressed in base-ten). For example, this:

will print 12 six times. (Note that this notation only affects how an integer literal is interpreted. The result of the arithmetic expansion is still expressed in base ten, regardless.)

For bases 11 through 36, the English letters A through Z are used for digit-values 10 through 35. This is not case-sensitive. For bases 37 through 64, however, it is specifically the lowercase English letters that are used for digit-values 10 through 35, with the uppercase letters being used for digit-values 36 through 61, the at-sign @ being used for digit-value 62, and the underscore _ being used for digit-value 63. For example, 64#@A3 denotes 256259 ( 62 × 64 2 + 36 × 64 + 3 ).

There are also two special notations: prefixing a literal with 0 indicates base-eight (octal), and prefixing it with 0x or 0X indicates base-sixteen (hexadecimal). For example, 030 is equivalent to 8#30 , and 0x6F is equivalent to 16#6F .

Integer variables

A variable may be declared as an integer variable — that is, its "integer attribute" may be "set" — by using this syntax:

After running the above command, any subsequent assignments to n will automatically cause the right-hand side to be interpreted as an arithmetic expression. For example, this:

is more or less equivalent to this:

except that the first version's declare -i n will continue to affect later assignments as well.

In the first version, note the use of quotes around the right-hand side of the assignment. Had we written n=2 + 3 > 4 , it would have meant "run the command + with the argument 3 , passing in the environment variable n set to 2 , and redirecting standard output into the file 4 "; which is to say, setting a variable's integer attribute doesn't affect the overall parsing of assignment statements, but merely controls the interpretation of the value that is finally assigned to the variable.

We can "unset" a variable's integer attribute, turning off this behavior, by using the opposite command:

The declare built-in command has a number of other uses as well: there are a few other attributes a variable can have, and declare has a few other features besides turning attributes on and off. In addition, a few of its properties bear note:

  • As with local and export , the argument can be a variable assignment; for example, declare -i n = 2 +3 sets $n 's integer attribute and sets it to 5 .
  • As with local and export , multiple variables (and/or assignments) can be specified at once; for example, declare -i m n sets both $m 's integer attribute and $n 's.
  • When used inside a function, declare implicitly localizes the variable (unless the variable is already local), which also has the effect of locally unsetting it (unless the assignment syntax is used).

Non-integer arithmetic

As mentioned above, Bash shell arithmetic only supports integer arithmetic. However, external programs can often be used to obtain similar functionality for non-integer values. In particular, the common Unix utility bc is often used for this. The following command:

prints 5.6 . Needless to say, since bc is not so tightly integrated with Bash as shell arithmetic is, it is not as convenient; for example, something like this:

would, to support non-integers, become something like this:

Part of this is because we can no longer use an arithmetic for-loop; part of it is because referring to variables and assigning to variables is trickier now (since bc is not aware of the shell's variables, only its own, unrelated ones); and part of it is because bc communicates with the shell only via input and output.

  • ↑ http://www.sal.ksu.edu/faculty/tim/unix_sg/bash/math.html

bash compound assignment

  • Book:Bash Shell Scripting
  • Pages using deprecated enclose attributes

Navigation menu

  • Share full article

Advertisement

Supported by

Wednesday Briefing

Narendra Modi’s election setback in India.

Daniel E. Slotnik

By Daniel E. Slotnik

Narendra Modi, white-haired and bearded, raises his hands in peace signs as he is showered with confetti. A crowd cheers and celebrates behind barricades.

Modi won, but his party suffered losses

Prime Minister Narendra Modi of India claimed a third term in office yesterday. But his party won by a far narrower margin than expected, and the aura of invincibility around Modi has been shattered .

His Bharatiya Janata Party still won the most parliamentary seats, but it lost dozens of them and was left without enough for an outright majority. So the B.J.P. will need smaller parties in its coalition to form a government, a surprising setback.

See results and takeaways .

The Indian National Congress, the main opposition, did better than expected . The party had been seen by many as irrevocably weakened after big losses in the previous two elections. The Congress and its allies increased their margin against Modi by tapping into issues like unemployment, social justice and the prime minister’s ties to India’s billionaires.

Context: Modi will be only the second Indian leader to start a third straight term, after Jawaharlal Nehru, the first prime minister. Modi called the third term “ a historical feat in India’s history .”

Economy: As the election results became clearer, India’s stock markets plunged . By the end of trading yesterday, the markets were down 6 percent, nearly wiping out the year’s gains.

What Ukraine has lost

Since World War II, few countries have experienced the level of devastation that Ukraine has. But until now, the scale has been too vast to see more than a glimpse at a time.

My colleagues published the first comprehensive picture of the destruction. Using detailed analysis of years of satellite data, they created a record of each town, each street, each building that has been blown apart. In some places, like the city of Marinka, not a single resident is left. So many people have lost more than their homes. They’ve lost their communities, their histories.

“If I shut my eyes, I can see everything from my old life,” said Iryna Hrushkovksa, 34, who was born and raised in the city. “But if I open my eyes, it’s all gone.”

The scale of destruction: More buildings have been destroyed in Ukraine than if every building in Manhattan were to be leveled four times over. Parts of Ukraine look like Dresden or London after World War II, or Gaza after half a year of bombardment.

HIMARS: Ukraine used a U.S.-made rocket system to destroy missile launchers inside Russia, a Ukrainian official said. The strikes came just after the U.S. granted permission for Ukraine to do so.

Israel killed an Iranian general in Syria

Israeli airstrikes in Syria killed an Iranian general who was there as an adviser, the Iranian media said. He was believed to be the first Iranian killed by Israel since the two countries almost went to war in April, after Israel bombed Iran’s embassy compound in Syria.

Iran is currently enmeshed in a leadership crisis stemming from the death of its president last month. A new wave of attacks on Israel seems unlikely. The Iranian was identified as Gen. Saeed Abyar, a member of the Quds Force, a branch of the Revolutionary Guards.

Gaza: Some Gazans are urging Hamas to accept a cease-fire plan proposed by President Biden, but remain skeptical that the U.S. would truly bring an end to the war. In an interview with Time magazine, Biden suggested that Prime Minister Benjamin Netanyahu of Israel was prolonging the war to stay in power.

MORE TOP NEWS

Britain: Prime Minister Rishi Sunak and his Labour Party opponent, Keir Starmer, clashed over taxes, immigration and health care in a televised debate yesterday.

Asylum: President Biden issued an executive order that would temporarily seal the U.S.-Mexico border to those seeking asylum when crossings surge.

France: Biden will begin a visit today , during which he will try to rally U.S. allies in defense of Ukraine — even as he defies them on the war in Gaza.

U.S.: Louisiana lawmakers passed a bill that could order people who are convicted of child molestation to undergo surgical castration .

Brazil: Climate change worsened recent flooding, scientists said. Downpours there killed at least 172 people and displaced more than half a million.

OpenAI: A group of current and former employees warned that the company had not done enough to prevent its technology from becoming dangerous .

Covid: New strains, known as “FLiRT” variants , are circulating in the U.S., but there has been only a small increase in emergency room visits and positive tests.

Music: The hip-hop mogul Sean Combs has sold his majority stake in Revolt , the media company he founded, as he faces accusations of sexual and physical abuse.

MORNING READ

Benjamin Bolger has spent his life amassing academic degrees . He has 14 advanced degrees, including a few that took many years to complete, such as a doctorate from the Harvard Graduate School of Design.

The reason for his university quest is simple: “I love learning,” he told our reporter.

CONVERSATION STARTERS

Ask Climate: For an eco-friendly way to control backyard bugs, try the “ bucket of doom .”

Right after the Big Bang: A new observatory in Chile is investigating a mystery from the beginning of time .

SPORTS NEWS

The Transfer DealSheet: A weekly guide to transfers across Europe this summer.

Moving on: The driver Esteban Ocon will leave the Alpine team at the end of the Formula 1 season.

French Open: Novak Djokovic withdrew because of an injury , and Coco Gauff, Iga Swiatek and Carlos Alcaraz all won.

ARTS AND IDEAS

Chinese websites are disappearing.

China’s internet is vanishing in chunks. Posts are being removed and censored.

As of 2023, there were 3.9 million sites, down from 5.3 million in 2017, the country’s internet regulator found. A recent post on WeChat reported that nearly all information shared on China’s internet — news portals, blogs, forums, social media sites — between 1995 and 2005 was no longer available.

While archiving a website anywhere is costly and difficult, internet publishers in China are under intense pressure to censor under Xi Jinping’s leadership, Li Yuan writes in the column The New New World.

Internet companies have more incentive to overcensor and to let older content disappear by not archiving.

Two weeks ago, Nanfu Wang, a documentary filmmaker, searched her name on the film review site Douban and found nothing. “Some of the films I directed had been deleted and banned on the Chinese internet,” she said. “But this time, I feel that I, as a part of history, have been erased.”

RECOMMENDATIONS

Cook: This shrimp scampi comes together in one skillet.

Read: In the novel “ Blessings ,” a gay Nigerian boy works to understand himself in an often hostile country.

Watch: A grande dame of theater faces a complex reckoning in “ The Great Lillian Hall .”

Play the Spelling Bee . And here are today’s Mini Crossword and Wordle . You can find all our puzzles here .

That’s it for today’s briefing. Thank you for spending part of your morning with us, and see you tomorrow. — Dan

P.S. The Times has surpassed two million digital subscribers outside the U.S.

You can reach Dan and the team at [email protected] .

Daniel E. Slotnik is a general assignment reporter on the Metro desk and a 2020 New York Times reporting fellow. More about Daniel E. Slotnik

Next: The Directory Stack , Previous: Aliases , Up: Bash Features   [ Contents ][ Index ]

Bash provides one-dimensional indexed and associative array variables. Any variable may be used as an indexed array; the declare builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions (see Shell Arithmetic )) and are zero-based; associative arrays use arbitrary strings. Unless otherwise noted, indexed array indices must be non-negative integers.

An indexed array is created automatically if any variable is assigned to using the syntax

The subscript is treated as an arithmetic expression that must evaluate to a number. To explicitly declare an array, use

is also accepted; the subscript is ignored.

Associative arrays are created using

Attributes may be specified for an array variable using the declare and readonly builtins. Each attribute applies to all members of an array.

Arrays are assigned to using compound assignments of the form

where each value may be of the form [ subscript ]= string . Indexed array assignments do not require anything but string . When assigning to indexed arrays, if the optional subscript is supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero.

Each value in the list undergoes all the shell expansions described above (see Shell Expansions ).

When assigning to an associative array, the words in a compound assignment may be either assignment statements, for which the subscript is required, or a list of words that is interpreted as a sequence of alternating keys and values: name =( key1 value1 key2 value2 … ). These are treated identically to name =( [ key1 ]= value1 [ key2 ]= value2 … ). The first word in the list determines how the remaining words are interpreted; all assignments in a list must be of the same type. When using key/value pairs, the keys may not be missing or empty; a final missing value is treated like the empty string.

This syntax is also accepted by the declare builtin. Individual array elements may be assigned to using the name [ subscript ]= value syntax introduced above.

When assigning to an indexed array, if name is subscripted by a negative number, that number is interpreted as relative to one greater than the maximum index of name , so negative indices count back from the end of the array, and an index of -1 references the last element.

The ‘ += ’ operator will append to an array variable when assigning using the compound assignment syntax; see Shell Parameters above.

Any element of an array may be referenced using ${ name [ subscript ]} . The braces are required to avoid conflicts with the shell’s filename expansion operators. If the subscript is ‘ @ ’ or ‘ * ’, the word expands to all members of the array name . These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${ name [*]} expands to a single word with the value of each array member separated by the first character of the IFS variable, and ${ name [@]} expands each element of name to a separate word. When there are no array members, ${ name [@]} expands to nothing. If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. This is analogous to the expansion of the special parameters ‘ @ ’ and ‘ * ’. ${# name [ subscript ]} expands to the length of ${ name [ subscript ]} . If subscript is ‘ @ ’ or ‘ * ’, the expansion is the number of elements in the array. If the subscript used to reference an element of an indexed array evaluates to a number less than zero, it is interpreted as relative to one greater than the maximum index of the array, so negative indices count back from the end of the array, and an index of -1 refers to the last element.

Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0. Any reference to a variable using a valid subscript is legal, and bash will create an array if necessary.

An array variable is considered set if a subscript has been assigned a value. The null string is a valid value.

It is possible to obtain the keys (indices) of an array as well as the values. ${! name [@]} and ${! name [*]} expand to the indices assigned in array variable name . The treatment when in double quotes is similar to the expansion of the special parameters ‘ @ ’ and ‘ * ’ within double quotes.

The unset builtin is used to destroy arrays. unset name [ subscript ] destroys the array element at index subscript . Negative subscripts to indexed arrays are interpreted as described above. Unsetting the last element of an array variable does not unset the variable. unset name , where name is an array, removes the entire array. unset name [ subscript ] behaves differently depending on the array type when given a subscript of ‘ * ’ or ‘ @ ’. When name is an associative array, it removes the element with key ‘ * ’ or ‘ @ ’. If name is an indexed array, unset removes all of the elements, but does not remove the array itself.

When using a variable name with a subscript as an argument to a command, such as with unset , without using the word expansion syntax described above, the argument is subject to the shell’s filename expansion. If filename expansion is not desired, the argument should be quoted.

The declare , local , and readonly builtins each accept a -a option to specify an indexed array and a -A option to specify an associative array. If both options are supplied, -A takes precedence. The read builtin accepts a -a option to assign a list of words read from the standard input to an array, and can read values from the standard input into individual array elements. The set and declare builtins display array values in a way that allows them to be reused as input.

COMMENTS

  1. Linux Bash: Multiple Variable Assignment

    Using the multiple variable assignment technique in Bash scripts can make our code look compact and give us the benefit of better performance, particularly when we want to assign multiple variables by the output of expensive command execution. For example, let's say we want to assign seven variables - the calendar week number, year, month ...

  2. Bash Assignment Operators (Shell Scripting)

    In bash programming, assignment operators are like tools that let you give values to things. For example, you can tell the computer that "x equals 5" or "name equals tecadmin". ... Compound Assignment Operators. The compound assignment operators combination of performing some operation and then assign value to variable in a single ...

  3. Using compound conditions in a Bash shell script

    In Bash, the double parentheses set up an arithmetic context (in which dollar signs are mostly optional, by the way) for a comparison (also used in for ((i=0; i<=10; i++)) and $(()) arithmetic expansion) and is used to distinguish the sequence from a set of single parentheses which creates a subshell. This, for example, executes the command ...

  4. Bash Reference Manual

    Bash Features. This text is a brief description of the features that are present in the Bash shell (version 5.2, 19 September 2022). ... Assignment statements may also appear as arguments to the alias, declare, typeset, export, readonly ... When '+=' is applied to an array variable using compound assignment (see Arrays), the variable's ...

  5. Bash Logical Operators

    In Bash, the += operator is a compound assignment operator that allows you to add (concatenate) a string or value to the end of an existing variable's value. It's commonly used for building or modifying strings dynamically in scripts. What is binary operator in Bash? A binary operator in Bash is an operator that works on two operands or

  6. Mastering Variable Assignment In Bash: Syntax, Manipulation, Scopes

    In Bash, concatenating strings involves combining multiple strings into a single string. This can be useful when you want to create a new string by combining existing strings or adding additional text. To concatenate strings in Bash, you can use the concatenation operator (+) or the compound assignment operator (+=).

  7. Mastering Operators in Shell Scripting: A Comprehensive Guide

    4. Assignment Operators. Assignment operators are used to assign values to variables in shell scripts. The basic assignment operator is =. However, there are also compound assignment operators that combine an operation with assignment, such as +=, -=, *=, and /=. Here's an example of using assignment operators in a shell script:

  8. Compound Commands (Bash Reference Manual)

    Compound commands are the shell programming language constructs. Each construct begins with a reserved word or control operator and is terminated by a corresponding reserved word or operator. Any redirections (see Redirections) associated with a compound command apply to all commands within that compound command unless explicitly overridden. In ...

  9. Bash Conditional Expressions (Bash Reference Manual)

    6.4 Bash Conditional Expressions. Conditional expressions are used by the [[compound command (see Conditional Constructs) and the test and [builtin commands (see Bourne Shell Builtins).The test and [commands determine their behavior based on the number of arguments; see the descriptions of those commands for any other command-specific actions. ...

  10. How to Work with Variables in Bash

    Here, we'll create five variables. The format is to type the name, the equals sign =, and the value. Note there isn't a space before or after the equals sign. Giving a variable a value is often referred to as assigning a value to the variable. We'll create four string variables and one numeric variable, my_name=Dave.

  11. bash-notes

    The example above, ${fruits[@]} expands to the entire contents of the array and substitutes it into the compound assignment, then assigns the new value into the fruits array mutating its original value. Deleting elements from an array. ... Bash has powerful tools for working with other programs and their outputs. Using streams we can send the ...

  12. shell

    As WP says, $(()) can only contain arithmetic expressions and therefore, a general ternary assignment doesn't exist in Bash. - zakmck. Apr 10, 2023 at 18:49. @zakmck i think you should check again. try the code in the example. - mikeserv. Sep 24, 2023 at 2:07.

  13. Bash Math Operations (Bash Arithmetic) Explained

    The preferable way to do math in Bash is to use shell arithmetic expansion. The built-in capability evaluates math expressions and returns the result. The syntax for arithmetic expansions is: $((expression)) The syntax consists of: Compound notation (()) which evaluates the expression. The variable operator $ to store the result.

  14. Bash Shell Scripting/Shell Arithmetic

    The notation for this is similar to that of regular variable assignment, but is much more flexible. For example, the previous example could be rewritten like this: ... Bash also supports compound operators such as +=, -=, *=, /=, and %=, which perform an operation followed by an assignment.

  15. Bash Variables (Bash Reference Manual)

    Assignment to BASH_ARGV0 causes the value assigned to also be assigned to $0. If BASH_ARGV0 is unset, it loses its special properties, ... The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTCONTROL.

  16. Wednesday Briefing

    P.S. The Times has surpassed two million digital subscribers outside the U.S. You can reach Dan and the team at [email protected]. Daniel E. Slotnik is a general assignment reporter on the ...

  17. Israel strike on UN school that left dozens dead used US ...

    CNN has reached out to UNRWA for comment. Palestinians gather outside a UN-run school after it was hit by an Israeli airstrike on June 6, 2024. The attack also came as American, Egyptian and ...

  18. Arrays (Bash Reference Manual)

    Bash provides one-dimensional indexed and associative array variables. ... The '+=' operator will append to an array variable when assigning using the compound assignment syntax; see Shell Parameters above. Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with the shell's ...

  19. Saeed Abiyar: Iranian military adviser killed in Syria, reports say

    Israeli airstrikes near the Syrian city of Aleppo early Monday killed an Iranian military adviser, Iranian media reported, two months after the Middle East came to the brink of a major war as ...

  20. Bash arrays: compound assignments fail

    $ sh test.sh SHELL=/bin/bash Single-quoted v: v[0]=(a b c) v[1]= v[2]= Double-quoted v: v[0]=(a b c) v[1]= v[2]= Unquoted v: v[0]=a v[1]=b v[2]=c If you quote the assignment, it becomes a simple variable assignment; a simple mistake to make that is easily overlooked.

  21. 5 things to know for June 6: D-Day, Gaza, Trump, Covid-19, Severe ...

    4. Covid-19. Another new version of the Covid-19 vaccine will likely be coming this fall. A group of FDA vaccine advisers voted unanimously on Wednesday to recommend that the agency tell vaccine ...

  22. syntax

    bash integer variables. In addition to, dutCh, Vladimir and ghostdog74's corrects answers and because this question is regarding integer and tagged bash: Is there a way to do something like this. int a = (b == 5) ? c : d; There is a nice and proper way to work with integers under bash:

  23. Nobel Prize-winning chemist Thomas R. Cech on 'The Catalyst' and the

    In his new book "The Catalyst," Thomas R. Cech talks about the Covid-19 vaccines, what RNA means for future health crises and how gene editing with CRISPR factors in.

  24. Compound associative array variable assignment in Bash fails when read

    Was expecting that the array's compound keys-values assignment reading from variable or command substituion would work. P.S. I think Bash: set associative array from variable answers my issue. The easiest for me to comprhende answer was the eval statement put in double quotes, which seems to work for me. e.g. ... #!/usr/bin/env bash # Capture ...