Stack Exchange Network
Stack Exchange network consists of 181 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.

Conditional assignments in bash
In bash (and zsh ), how do I most concisely assign the value of $1 to the variable w , if $1 is given, and otherwise a default value 4 ?
but that returned an error message.
Is there anything simpler than
- I am somewhat surprised that you tagged the question with bash but quote a zsh error message ... – AdminBee Mar 18, 2020 at 12:46
- @AdminBee, sorry. but i'd prefer something that works in both. – Toothrot Mar 18, 2020 at 12:47
- I understand. You may want to edit your question to point that out, though, it might attract "bashisms" otherwise ;) (there, I used a new word I learned recently!) – AdminBee Mar 18, 2020 at 12:49
Use a parameter expansion of the form ${parameter:-word}
${parameter:-word} Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
Omitting the colon results in a test only for a parameter that is unset.
Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged bash zsh or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
Hot Network Questions
- Linear regulator thermal information missing in datasheet
- How do you ensure that a red herring doesn't violate Chekhov's gun?
- In Dungeon World, is the Bard's Arcane Art subject to the same failure outcomes as other spells?
- Why do academics stay as adjuncts for years rather than move around?
- Why does Mister Mxyzptlk need to have a weakness in the comics?
- Is it correct to use "the" before "materials used in making buildings are"?
- How does fire heat air?
- How to match a specific column position till the end of line?
- Styling contours by colour and by line thickness in QGIS
- FAA Handbooks Copyrights
- How did “obarray” get its name?
- What did Ctrl+NumLock do?
- Is there a single-word adjective for "having exceptionally strong moral principles"?
- How to tell which packages are held back due to phased updates
- What is the point of Thrower's Bandolier?
- Magento 2 community edition
- Why do many companies reject expired SSL certificates as bugs in bug bounties?
- Can airtags be tracked from an iMac desktop, with no iPhone?
- What is a word for the arcane equivalent of a monastery? A place where magic is studied and practiced?
- Why do small African island nations perform better than African continental nations, considering democracy and human development?
- Why are Suriname, Belize, and Guinea-Bissau classified as "Small Island Developing States"?
- Difficulties with estimation of epsilon-delta limit proof
- Linear Algebra - Linear transformation question
- Biodiversity through radiation
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
Stack Exchange Network
Stack Exchange network consists of 181 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Comparing two strings in zsh
I've been looking everywhere for what should be a simple example. First time trying to script something for zsh now that MacOS has switched over to it as default - how do I compare two strings in an if statement? I tried the following but continue to receive the error no matches found: [foo==foo]
- conditional-statements
How do I compare two strings in an if statement?
Use the following:

- 3 Maybe it's worth pointing out that the white space around the operator == is essential, and not the doubled brackets as one might guess. – mpy Apr 20, 2020 at 18:08
- @mpy I would if I could find a good reference - I did look .... – DavidPostill ♦ Apr 20, 2020 at 18:10
- I neither have found a statement in the manual, but even with [[ (which should always be preferred over [ , please don't get me wrong on that) you don't get the desired behavior without white spaces around the operator. – mpy Apr 20, 2020 at 20:50
- 3 @mpy - I get zsh: = not found , if I have no whitespace between foo and the square brackets [] - like this if ["foo" == "foo"] or [["foo" == "foo"]] , and no errors with no whitespace between foo and the double equality sign == with either [[ "foo"=="foo" ]] or [ "foo"=="foo" ] , so as per my experiments it's most important to have space between the square brackets and the string/variable start point and end point like this [[ "foo"=="foo" ]] and not like this too if [["foo"=="foo"]] , which produces error like zsh: no matches found: [[foo==foo]] – aspiring1 May 23, 2021 at 12:06
- @aspiring1: Yes, you are right! I obviously mixed something up, the white space around the brackets is important. This is sensible, because the [ was first implemented as an external function, so it has to be separated from its arguments. And probably this was then taken onward to the shell built-ins [ and [[ . – mpy May 24, 2021 at 10:08
Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged zsh conditional-statements or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup

Hot Network Questions
- Do new devs get fired if they can't solve a certain bug?
- In Dungeon World, is the Bard's Arcane Art subject to the same failure outcomes as other spells?
- How can I check before my flight that the cloud separation requirements in VFR flight rules are met?
- Edges of each colour for Ramsey Graphs
- Counting Letters in a String
- Why is this sentence from The Great Gatsby grammatical?
- Why are physically impossible and logically impossible concepts considered separate in terms of probability?
- Styling contours by colour and by line thickness in QGIS
- Linear regulator thermal information missing in datasheet
- Can airtags be tracked from an iMac desktop, with no iPhone?
- Can I tell police to wait and call a lawyer when served with a search warrant?
- Identify those arcade games from a 1983 Brazilian music video
- Did any DOS compatibility layers exist for any UNIX-like systems before DOS started to become outmoded?
- How do you get out of a corner when plotting yourself into a corner
- Is there a single-word adjective for "having exceptionally strong moral principles"?
- Using Kolmogorov complexity to measure difficulty of problems?
- How can this new ban on drag possibly be considered constitutional?
- Relation between transaction data and transaction id
- Is it correct to use "the" before "materials used in making buildings are"?
- How can we prove that the supernatural or paranormal doesn't exist?
- Short story taking place on a toroidal planet or moon involving flying
- FAA Handbooks Copyrights
- Do I need a thermal expansion tank if I already have a pressure tank?
- AC Op-amp integrator with DC Gain Control in LTspice
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
- Stack Overflow Public questions & answers
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Talent Build your employer brand
- Advertising Reach developers & technologists worldwide
- About the company
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
zsh conditional OR fails
however if I change
if [ "$BRANCH" = 'master' || "$BRANCH" = 'develop' ]; then
if [ "$BRANCH" = 'master' ]; then
eveything works. How can I do OR comparison?
- try -o instead of || . – Fabian Klötzl Jun 28, 2017 at 7:19
2 Answers 2
You have two primary options (of course there are also some less straight forward ones)
Use zsh syntax and use [[ ... ]] instead of [ ... ] .
Use -o instead of || in order to stay POSIX compliant
If the code is only ever to be run with zsh , I would recommend to go with 1.
The reason for the error message is that [ is only a regular command and not part of the zsh syntax. [ expects ] as last parameter, but || is part of the zsh syntax and has priority. It acts as a separator between commands and splits the "condition" into two commands
The second command is run, if the first one fails.
Running the first command fails, as the the closing ] is missing. This leads to the error message:
For the second command "$BRANCH" is substituted by the value master . As there is no command named master this returns the error message
You should run your shell script in debug mode, eg 'zsh -x', it'll spit out what variables are at each step so you have a good understanding of what's happening.
The BRANCH variable is being clobbered here; The -n checks to see if BRANCH has a value and if so updates it. I expect you meant to use the -z switch;
I think your script should look more like

Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged zsh or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
- Launching the CI/CD and R Collectives and community editing features for...
- The [amazon] tag is being burninated
- Temporary policy: ChatGPT is banned
- Staging Ground Beta 1 Recap, and Reviewers needed for Beta 2
Hot Network Questions
- Why do small African island nations perform better than African continental nations, considering democracy and human development?
- If you preorder a special airline meal (e.g. vegan) just to try it, does this inconvenience the caterers and staff?
- Why does Mister Mxyzptlk need to have a weakness in the comics?
- Knocking Out Zombies
- Linear regulator thermal information missing in datasheet
- Is a PhD visitor considered as a visiting scholar?
- Copyright issues when journal is defunct
- Using Kolmogorov complexity to measure difficulty of problems?
- Why do academics stay as adjuncts for years rather than move around?
- Does Counterspell prevent from any further spells being cast on a given turn?
- FAA Handbooks Copyrights
- Can I tell police to wait and call a lawyer when served with a search warrant?
- How to use Slater Type Orbitals as a basis functions in matrix method correctly?
- OK to delete Windows.db file on PC?
- Follow Up: struct sockaddr storage initialization by network format-string
- "After the incident", I started to be more careful not to trip over things. - the incident has nothing to do with me; can I use this this way?
- Can Martian regolith be easily melted with microwaves?
- Magento 2 community edition
- My code is GPL licensed, can I issue a license to have my code be distributed in a specific MIT licensed project?
- Question on Step X of Rudin's proof of the Riesz Representation Theorem
- Seal script identification/translation
- In Dungeon World, is the Bard's Arcane Art subject to the same failure outcomes as other spells?
- What can a lawyer do if the client wants him to be acquitted of everything despite serious evidence?
- What is the purpose of this D-shaped ring at the base of the tongue on my hiking boots?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
Chapter 5: Substitutions
5.1: quoting, 5.1.1: backslashes, 5.1.2: single quotes, 5.1.3: posix quotes, 5.1.4: double quotes, 5.1.5: backquotes, 5.2: modifiers and what they modify, 5.3: process substitution, 5.4: parameter substitution, 5.4.1: using arrays, 5.4.2: using associative arrays, 5.4.3: substituted substitutions, top- and tailing, etc., 5.4.4: flags for options: splitting and joining, 5.4.5: flags for options: glob_subst and rc_expand_param, 5.4.6: yet more parameter flags, 5.4.7: a couple of parameter substitution tricks, 5.4.8: nested parameter substitutions, 5.5: that substitution again, 5.6: arithmetic expansion, 5.6.1: entering and outputting bases, 5.6.2: parameter typing, 5.7: brace expansion and arrays, 5.8: filename expansion, 5.9: filename generation and pattern matching, 5.9.1: comparing patterns and regular expressions, 5.9.2: standard features, 5.9.3: extensions usually available, 5.9.4: extensions requiring extended_glob, 5.9.5: recursive globbing, 5.9.6: glob qualifiers, 5.9.7: globbing flags: alter the behaviour of matches, 5.9.8: the function zmv.
- IT Management
- Infrastructure
- High Performance

How to Write Scripts for zsh
Believe it or not, these “built-in” completions are simply shell functions. If you want to customize the behavior of your command line, you can edit existing completion functions or create your own. This month, we’ll look at basic zsh scripting and learn some fundamental skills as preparation for next month’s column on programming completions.
The zsh scripting language extends the Bourne shell syntax and can be quite complicated. Set aside some time to experiment and don’t underestimate the learning curve because it’s “only shell scripting.” Mastering the basic concepts will take some effort.
Let’s start with a simple problem. Suppose you have a directory hierarchy full of text files with their execute permission bit set. How can you recursively turn off the execute permission for files, but leave the execute permissions for the directories alone? With the Bourne shell, you might do something like this:
Using zsh and globs (special strings containing wildcard characters like ? , * , etc.) the solution is simpler. zsh ‘s globbing abilities are good enough to make find unnecessary. We need only run this to get the same result:
The leading **/ tells zsh to glob recursively. The * following that means to get everything. Finally, the glob ends in a (.) , which is a glob qualifier , that restricts the matching to files.
Here’s another example (with additional glob qualifiers). Suppose an unwanted visitor compromised the security of your machine, and you want to find out if he implanted any trojan horses (trojan horses are programs that disguise themselves as regular Linux commands like passwd and then transmit stolen information back to the evildoer) and check the entire filesystem to see if any executable files have been modified since yesterday. In zsh , this can be done with:
Notice how glob qualifiers can be chained together. This time, we have “ * ” which means executables, “ . ” which means plain files, and “ m-1 ” which limits matches to anything with a modification time of one day or less. The -l option tells print to print out each value on a separate line. As you can see, using glob qualifiers together with recursive globbing makes zsh ‘s globbing system just as powerful as the find program.
For a full list of glob qualifiers, see the “Glob Qualifiers” section of the zshexpn man page. For more on filename generation and pattern matching, see section 5.9 of the Zsh User’s Guide ( http://zsh.sunsite.dk/Guide/ ).
Data Types and Attributes
We’ve just seen how globbing can generate huge lists of filenames. But once you have a list, the question is how to contain it. An array works perfectly for this. In the following command, list will be assigned a list of all the files in /usr/bin .
This array can then be accessed in a number of ways that programmers (especially Perl programmers) may find familiar. However, be careful. In zsh , arrays are indexed from 1 instead of 0. Below are some examples using arrays.
To get the array size, use a $# before the array name:
Both positive numbers and negative numbers can be used as indexes into the array. Positive numbers count forward from the start of the array; negative numbers count backward from the end of the array:
To retrieve multiple values as a sub-list (or a “slice”), we can add a comma between starting and ending index numbers:
The array is just one of zsh ‘s five data types. The other four types are: association (a hash table), scalar (a string), float, and integer. In general, type is handled automatically (as far as the programmer is concerned). For example, the following code assigns a scalar value to theory , a float to pi , and an integer to a without the need for type to be declared explicitly:
However, one exception is associations. You must first declare a variable as an associative array before it takes on the behavior of one. This is done by using the built-in command typeset -A variable :
typeset is actually quite versatile. It can be used to pre-declare variables of specific types (scalar, int, float, array), although it’s not strictly necessary. It can also give special attributes to variables. Let’s look at some examples.
The -Z 3 option makes the variable agent at least three characters long, padded with zeros if necessary.
The -r option can make a variable read-only.
The -U option forces an array to have unique contents and duplicate values are ignored.
zsh can also tie scalar variables and array variables together with the -T option, effectively giving you two interfaces to the same data. In Figure One , you can see how the variables $DIR and $dir are tied together.
This feature is extremely useful for dealing with “PATH-like” variables. In fact, the $PATH , $FPATH , and $MANPATH environment variables already have matching $path , $fpath , and $manpath variables associated with them when zsh starts up. And since arrays can’t be exported, being able to store the array’s contents into a single string is very useful.
(The reason arrays can’t be exported is because the shell environment is a feature of Unix, not a part of zsh . zsh can support any the data types it wants, but the environment only understands strings. This prevents collections like arrays or associations from being exported. However, float, integer, and scalar variables can be exported without problems.)
For more on typeset , use tab-completion to see a complete list of available special attributes (by typing typeset -[TAB] ) or read the zshbuiltins man page.
Using Flags and Modifiers to Transform Data
Now that we have data stored in variables, let’s learn how to manipulate it. In shell programming, data manipulation has traditionally been done by programs like sed and awk which are usually used in a long and contrived series of backticks and pipes. However, zsh scripts can often avoid this by using flags and modifiers. Let’s look at a simple example:
Here, we make the entire string upper-case, first using the (U) flag and then using the :u modifier. Then, we print $place without any modifiers or flags to show that the variable was not actually changed.
(Why a (U) flag and a :u modifier? There isn’t much difference between them; you may prefer one or the other depending on your coding style.)
Let’s initialize an array that we’ll use for some more examples:
One feature unique to modifiers is specialized filename transformations. A filename transformation can do the same things that basename and dirname can. We can use the -t flag to simulate basename and the -h flag to simulate dirname :
% print ${list:h} /usr/bin /var/log /etc
We can also simulate grep -v (inverted grep) using the :# modifier to filter out items from list that match the given glob pattern.
To simulate a normal grep, the (M) flag is used to reverse the meaning of :# .
Finally, you can combine and nest flags and modifiers to perform complex data manipulations. Unfortunately, the result often looks like line noise. In the next example, we store the complete path names of all entries from /usr/bin in list . Then we print out the file names (in upper case) of all entries that have “ssh” anywhere in the path.
For more on modifiers and parameter expansion flags, see the zshexpn man page.
Conditional Expressions using [[ ]]
That last example might may make you think that the zsh developers don’t care about readability, but that’s not completely true. Look at the improvements made to conditional expressions for reassurance that zsh code can in fact be readable.
zsh has an alternative method for writing conditionals that’s much more expressive than using the traditional test command. It’s greatest strength is its ability to nest conditionals using a familiar and intuitive notation. In the next example, notice how parentheses can be used for grouping, and && and || for logical AND and OR.
The [[ ]] notation is also downward compatible with the test command, being able to perform the same file and string tests. For example, you can use -e to see if a file exists, -d to see if a name is a directory, or perform string comparisons, in this case, inequality:
Mathematical Expressions Using (( ))
zsh also has a double parenthesis notation to evaluate mathematical expressions. The most interesting thing about (( )) is that its expression syntax is a radical departure from Bourne shell syntax. Consider the following example.
Everything in the example above, from the mathematical operators to how dollar signs are omitted when referring to variables, makes zsh look and feel a lot more like a C program than a shell script. While zsh ‘s syntax is definitely an improvement over expr and backticks, there are times when zsh can be a bit too much like C.
For example, the shell script below (just a one-liner typed at the command prompt) demonstrates that zsh ‘s type system doesn’t automatically promote integer types to yield the most accurate result. Instead, it’s necessary to explicitly specify one of the two numbers as a floating-point number to get the highest accuracy. Most scripting languages will perform the promotion for you, but whoever implemented the (( )) notation apparently liked C a lot.
% print $(( 5.0 / 2 )) 2.5
Besides being used for mathematical functions, (( )) is often used in statements needing conditional expressions. In these cases, expressions that evaluate to 0 are false and everything else is true (like C).
An idiom that you’ll see a lot in the completion functions is the $+var technique, which tests to see if $var is defined. Here are a few examples:
Notice also how the logical AND and OR act as if-then statements. This is just like Perl.
Portability
In addition to being powerful, zsh is also inherently portable. Plain Bourne shell scripts are notoriously difficult to write portably, because they rely heavily on external programs to do data transformation. Fortunately, zsh scripts don’t rely on external programs as much, because zsh has the capabilities of many traditional Unix programs built into it. We’ve already seen how it can emulate find , grep , basename , and dirname . Thus, for portability’s sake, you should use zsh ‘s built-in features over calling an external program whenever possible.
One more tip to make your zsh script as portable and reliable as possible: Since setopt can drastically change the behavior of zsh , add emulate -L zsh to the body of your script or function to start from a known state.
Hit the Books
Start experimenting with zsh on your own. Next month, we’ll look at writing completions with zsh.
Godot 4.0: A Viable Gaming Engine Alternative
Nextcloud taking on microsoft and google in germany and the eu, xfce apps update for february 2023, pinetab2 linux tablet comes in april starting at $159, kde gear 22.12.3 looks to improve kdenlive, ark, kate, more.
LinuxToday is a trusted, contributor-driven news resource supporting all types of Linux users. Our thriving international community engages with us through social media and frequent content contributions aimed at solving problems ranging from personal computing to enterprise-level IT operations. LinuxToday serves as a home for a community that struggles to find comparable information elsewhere on the web.
- Privacy Policy
- California – Do Not Sell My Information
Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.

IMAGES
VIDEO
COMMENTS
Zsh being zsh, there is a cryptic way: V=$ {$ {VERBOSE#0}:+$FOO} This sets V to the value of FOO if VERBOSE is a nonzero number, and to the empty string if VERBOSE is empty or 0. V=$ {$ {$ {VERBOSE/#/a}:#a1}:+foo} This sets V to the value of FOO if VERBOSE is the exact string 1, and to the empty string otherwise.
zsh - Conditional assignments in bash - Unix & Linux Stack Exchange Conditional assignments in bash Ask Question Asked 2 years, 11 months ago Modified 2 years, 11 months ago Viewed 143 times 2 In bash (and zsh ), how do I most concisely assign the value of $1 to the variable w, if $1 is given, and otherwise a default value 4? I tried
A conditional expressionis used with the [[compound command to test attributes of files and to compare strings. of the following unary or binary expressions: -afile true if fileexists. -bfile true if fileexists and is a block special file. -cfile true if fileexists and is a character special file. -dfile true if fileexists and is a directory.
conditional statements - Comparing two strings in zsh - Super User Comparing two strings in zsh Ask Question Asked 2 years, 10 months ago Modified 2 years, 10 months ago Viewed 11k times 11 I've been looking everywhere for what should be a simple example.
1 I'm trying to group conditional expressions in zsh. if [ [ ( ! chkchroot ) || ( $# -lt 1 ) ]]; then echo "usage: $0 [command]" echo " run this inside a chroot" return 1 fi However this fails with a parsing error. Here, chkchroot is a shell function. In pure POSIX, one can do this.
Use zsh syntax and use [ [ ... ]] instead of [ ... ]. if [ [ "$BRANCH" = 'master' || "$BRANCH" = 'develop' ]]; then Use -o instead of || in order to stay POSIX compliant if [ "$BRANCH" = 'master' -o "$BRANCH" = 'develop' ]; then If the code is only ever to be run with zsh, I would recommend to go with 1.
However, zsh has an easier way of making sure everything is quoted with a backslash when that's needed. It's a special form of parameter substitution, just one of many tricks you can do by supplying flags in parentheses: % read string This is a *string* with various `special' characters % print -r -- ${(q)string}
zsh - Conditional Expressions Conditional Expressions compound command to test attributes of files and to compare strings. Each expression can be constructed from one or more of the following unary or binary expressions: -a file true if file exists. -b file true if file exists and is a block special file. -c file
zsh has an alternative method for writing conditionals that's much more expressive than using the traditional test command. It's greatest strength is its ability to nest conditionals using a familiar and intuitive notation. In the next example, notice how parentheses can be used for grouping, and && and || for logical AND and OR.