J.L
J.L

Reputation: 21

Multiple variable assignments separated by space in single line in Bash

For variable assignment in bash, I usually do the following:

a=1
b=2
c=3

If it is done in a single line, it will be like:

a=1; b=2; c=3

Recently I have seen some codes like:

a=1 b=2 c=3

The assignment is separated by space and it is working. I have tried to google this approach but cannot quickly find a textbook answer. Right now I just know that, it works.

So, is this syntax supported by all shells, or is it a standard approach?

Upvotes: 2

Views: 2145

Answers (3)

KamilCuk
KamilCuk

Reputation: 141493

is it a standard approach?

Yes.

From posix shell language 2.9.1 Simple Commands emphasis mine:

A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.

[...]

If no command name results, variable assignments shall affect the current execution environment. [...]

It's also can be seen from shell grammar:

simple_command   : cmd_prefix cmd_word cmd_suffix
                 | cmd_prefix cmd_word
                 | cmd_prefix
                 | cmd_name cmd_suffix
                 | cmd_name

cmd_prefix       :            io_redirect
                 | cmd_prefix io_redirect
                 |            ASSIGNMENT_WORD
                 | cmd_prefix ASSIGNMENT_WORD

You may put as many as you want assignments (and redirections) before command. If there is no command, the assignments will affect current shell.

Upvotes: 1

chepner
chepner

Reputation: 531858

POSIX defines a simple command as

A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.

Note that an assignment "statement" falls under this definition: it's just one or more variable assignments without the optional words following them to specify an actual command.

Later in the same section, the semantics of such commandless assignments is given:

Variable assignments shall be performed as follows:

  • If no command name results, variable assignments shall affect the current execution environment.

Upvotes: 0

Zig Razor
Zig Razor

Reputation: 3525

Yes it works. A possible caveat is SC2155 in that you should declare and assign separately.

That being said it will work except for using multiple declare options between the parameters. Also note that the declare parameters will apply to all variables (in this case -i).

script0:

#!/bin/bash

declare a b c
a=foo
b=bar
c=baz

foo () {
    local a=1 b=2 c=3

    echo "From within func:"
    declare -p a
    declare -p b
    declare -p c
}

foo

echo "From outside func:"
declare -p a
declare -p b
declare -p c
Output:

$ ./script.sh
From within func:
declare -- a="1"
declare -- b="2"
declare -- c="3"
From outside func:
declare -- a="foo"
declare -- b="bar"
declare -- c="baz"

script1:

#!/usr/bin/env bash

declare -i a -a b c
a=foo
b=(bar)
c=baz

foo () {
    local -i a=1 -a b=(2) c=3

    echo "From within func:"
    declare -p a
    declare -p b
    declare -p c
}

foo

echo "From outside func:"
declare -p a
declare -p b
declare -p c
Output:

$ ./script.sh
./script.sh: line 3: declare: `-a': not a valid identifier
./script.sh: line 9: local: `-a': not a valid identifier
From within func:
declare -i a="1"
declare -ai b=([0]="2")
declare -i c="3"
From outside func:
declare -i a="0"
declare -ai b=([0]="0")
declare -i c="0"

Upvotes: 0

Related Questions