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

Toothrot's user avatar

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 .

Hot Network Questions

zsh conditional assignment

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]

Doofitator's user avatar

How do I compare two strings in an if statement?

Use the following:

DavidPostill's user avatar

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 .

Hot Network Questions

zsh conditional assignment

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 .

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?

DmitrySemenov's user avatar

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

Adaephon's user avatar

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

Calvin Taylor's user avatar

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 .

Hot Network Questions

zsh conditional assignment

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.

LinuxToday

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.

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

  1. Conditional Assignment

    zsh conditional assignment

  2. ZNotes

    zsh conditional assignment

  3. 3.3.1 Conditional Expressions Zybooks Java

    zsh conditional assignment

  4. Solved Dashboard Zybooks.com ooks My library > CS 2433C/C++

    zsh conditional assignment

  5. PHP operators Tutorial Example

    zsh conditional assignment

  6. Optimize mixins with conditionals in Sass

    zsh conditional assignment

VIDEO

  1. Bubbles Just Wants to be A Part of Everything 😂❤️

  2. Choo Choo Charles + Shredder = ???

  3. Krusty va a la Carcel

  4. POV: Me VS Friends mining diamonds Minecraft #minecraft #meme #memes #shorts #geming #tiktok

  5. #3generations #mom #grandma #beauty #funny #dancing #melanin #blackgirlmagic #3generations

  6. DIDI KI SHAADI 🥺

COMMENTS

  1. shell script

    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.

  2. zsh

    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

  3. zsh: 12 Conditional Expressions

    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.

  4. conditional statements

    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.

  5. How to group conditional expressions when using [ [ ]] in zsh

    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.

  6. zsh conditional OR fails

    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.

  7. A User's Guide to the Z-Shell

    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}

  8. zsh

    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

  9. How to Write Scripts for zsh

    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.