Variable

最後更新: 2021-09-21

目錄

  • 使用未宣告的 Variable
  • local 與 Global
  • env
  • $SHLVL
  • !$
  • Declaring a Bash Variable
  • Special parameters
  • Random Varable - $RANDOM
  • Substitution with a default value
  • Substitution for actual value
  • Substitution with value check
  • Parameter Length
  • Substring Starting Character
  • Remove Pattern
  • Find And Replace
  • Environmental variables
  • regex(=~)
  • stdin with EOF

 


使用未宣告的 Variable

 

當用到不存在的 var 時, 不會出 errror, 只是空白而已.

但它並不代表 Null !!

 


local 與 Global

 

  • local variables (在沒有指定是否 local 的情況下, 那 Default 所有 var 都是 Global 來, 即使在 function 內)
  • Global variables (environment variables)   <--- 可以用 printenv / env 查看所有 global variables

 


env

 

usage

env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]

opt

-i, --ignore-environment                       # start with an empty environment

-u, --unset=NAME

 


$SHLVL

 

Login 後是 1, 進入 screen 是 2

 


!$ - 最後的參數

 

root@ubuntu:/root# touch a
root@ubuntu:/root# touch b
root@ubuntu:/root# cat a b
root@ubuntu:/root# echo !$
echo b                                                 <-- 報行了什麼
b                                                      <-- 結果

 


Declaring a Bash Variable

 

Usage:

declare option variablename

Option:

  • -r read only variable
  • -i integer variable
  • -a array variable
  • -f for funtions
  • -x declares and export

 


Special parameters

 

The shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed.

Special bash variables

$*    Expands to the positional parameters, starting from one.

        When the expansion occurs within double quotes,
        it expands to a single word with the value of each parameter separated by the first character
        of the IFS special variable.

$@    Expands to the positional parameters, starting from one.

         When the expansion occurs within double quotes, each parameter expands to a separate word.

$#    Expands to the number of positional parameters in decimal.

$?    Expands to the exit status of the most recently executed foreground pipeline.

$-    A hyphen expands to the current option flags as specified upon invocation, by the set built-in command, or those set by the shell itself (such as the -i).

$$    Expands to the process ID of the shell.

$!    Expands to the process ID of the most recently executed background (asynchronous) command.

$0    Expands to the name of the shell or shell script.

i.e.

# /root/test/test.sh
/root/test/test.sh
# ./test.sh
./test.sh

$_      # underscore variable

此 var 有 3 大效果

1. It is set at shell startup and contains the absolute file name of the shell or script

    being executed as passed in the argument list.

ie.

bash

echo $_

/etc/bash_completion

2. It expands to the last argument to the previous command, after expansion.

應用

mkdir "/tmp/test space folder" && cd "$_"

3. full pathname used to invoke each command executed and placed in the environment exported to that command.

# Checking

env | grep '^_'

Note:

$* vs. $@

The implementation of "$*" has always been a problem and realistically should have been replaced with the behavior of "$@".

In almost every case where coders use "$*", they mean "$@". "$*" Can cause bugs and even security holes in your software.

$0 vs. ${BASH_SOURCE[0]}

${BASH_SOURCE}

An array variable whose members are the source filenames
contains the (potentially relative) path of the containing script in all invocation scenarios,
notably also when the script is sourced, which is not true for $0.

Script: foo.sh

#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"

bash ./foo.sh            # [./foo] vs. [./foo]

./foo.sh                    # [./foo] vs. [./foo]

. ./foo.sh                  # [bash] vs. [./foo]

 


Random Varable - $RANDOM

 

# Range: 0 - 32767

echo $RANDOM

27238

 

# retrieve random number between two limits.

RANGE=600
FLOOR=10

number=0                            #initialize
while [ "$number" -le $FLOOR ]
do
  number=$RANDOM
  let "number %= $RANGE"            # Scales $number down within $RANGE.
done
echo "Random number between $FLOOR and $RANGE ---  $number"

 


Substitution with a default value

 

${varname:-default}

If parameter is unset or null, the expansion of word is substituted.

Otherwise, the value of parameter is substituted.

echo "$VAR1"
VAR1="${VAR1:-default}"
echo "$VAR1"              # result: default value

${varname-default}                                   # 沒有 colon

當 parameter 是 null 時, 不會把 "default" assign 比 var

(亦即是說只有在 unset (not defined) 情況下才會取代, i.e. unset parameter)

VAR1=
echo ${VAR1-default}        # 沒有 output
echo ${VAR1:-default}       # output "default"

${varname:=default}     

echo ${varname:-default}
default
echo $varname               # 沒有東西
echo ${varname:=default}  
default
echo $varname
default                     # 指派並取代

 


Substitution for actual value

 

returns the substitute value if the variable is defined

${varname[:]+substitute}

 


Substitution with value check

 

# Display an Error Message If $VAR Not Passed

${varname[:]?message}

i.e.

${varName?Error varName is not defined}

${varName:?Error varName is not defined or is empty}

 


Parameter / Variable Length

 

Parameter length

$#

Variable length

myvar="123456"              # 6

echo "${#myvar}"

6

 


Substring

 

${var:start:end}

i.e.

test.txt

"abcd"
"1234"

1) 保留由 "1" 之後的

test.sh

while read line
do
        echo ${line:1}
done < "test.txt"

output

abcd"
1234"

2) 不要首尾

Code

echo ${line:1:-1}

output

abcd
1234

 


Remove Pattern

 

# 由開始刪除 Pattern - #, ##

  • ${var#Pattern}        # Remove from $var the shortest part of $Pattern
  • ${var##Pattern}      # Remove from $var the longest part of $Pattern

i.e.

var1=123abc123123

echo "${var1#1*1}"      # result: 23123

# 由開始刪除 Pattern - %, %%

  • %                # shortest part
  • %%             # longest part

i.e.

var1=123abc123123

echo "${var1%1*3}" # reault: 123abc123

 


Find And Replace

 

# only replace first occurrence

${varName/Pattern/Replacement}

# Find and replace all occurrences

${var//pattern/string}

 


Environmental variables

 

# key-value pairs

KEY=value1

# 當 KEY 有多個 vaule 時, 每個都用 colon (:) 分隔

KEY=value1:value2:...

# 有 white-space 時, 用 " 括住佢地

KEY="value with spaces"

 * inherited by any child shells or processes

Printing Environmental Variables

# All

printenv

# Variable name SHELL

printenv SHELL

用另一組 Environmental Variables 去行 program (env)

env - run a program in a modified environment

env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]

-u, --unset=NAME                      # remove variable from the environment
-i, --ignore-environment              # start with an empty environment

If no COMMAND, print the resulting environment.

Environmental Variable 與 Shell Variable 的分別

Shell Variable

 * in our current session, but will not be passed down to child(shell)

Printing Shell Variables

set

Creating

# Shell Variable

TEST_VAR='Hello World!'

# Environmental Variables

export NEW_VAR="Testing export"

Example 說故事

#!/bin/bash

A=1

A=2 printenv A
A=2 echo $A

 


regex(=~)

 

To compare a string with a regular expression pattern

Syntax

[[ string =~ regular_expression ]]

Example: 檢查是否 IP 地址

IP=$1
REGEX="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
    
if [[ $IP =~ $REGEX ]]; then
    ...
fi

Notes

[0-9]{1,3} 係粗略版, 會有錯誤內容, 如 0.x.x.x 或 300.x.x.x 之類

 


stdin with EOF

 

# Read from stdin until EOF
while IFS= read -r line
do
    echo "Get stdin: $line"
done

Opts

"IFS="

prevent leading/trailing whitespace from being trimmed.

"-r"

prevents backslashes from being interpreted as escape characters.

Test

./stdio.sh

test

You entered: test

test

You entered: test

?? ENTER ???? Ctrl+D to signal EOF

 


 

 

Creative Commons license icon Creative Commons license icon