Bash tips

8.13

变量相加

$((a + b))

数组长度

${#array}

String replace

  • ${string/pattern/new} replace
  • ${string//pattern/new} replace all
message='The secret code is 12345'
echo ${message/[0-9]/X}
# The secret code is X2345

echo ${message//[0-9]/X}
# The secret code is XXXXX

获取文件列表

files=$(ls /path/to/*.txt)
echo $files

for f in $files
do
  echo $f
done

Single quotes / double quotes

Single quotes won't interpolate anything, but double quotes will. For example, variables, expressions, backticks, certain \ escapes, etc.

Example

echo "$(echo "upg")"
# upg

echo '$(echo "upg")'
# $(echo "upg")

difference-between-single-and-double-quotes-in-bash

function

# $1, $2, ... $n, ..., $#
greeting () {
  echo "Hello $1"
}

greeting "Joe"

result="$(greeting 'Joe')"

bash functions

Check if file exists

使用条件判断和-f参数

test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
FILE = /ect/resolve.conf
if [ -f "$FILE" ]; then
    echo "$FILE exists."
else
    echo "$FILE does not exist"
fi

How to Check if a File or Directory Exists in Bash | Linuxize

判断字符串为空(string is null or empty)

status=`git status | grep commit`

if [ ! -z "$status" ]; then
    echo 'is not empty'
else
    echo 'is empty'
fi

比较字符串

  • [ string1 = string2 ]: equal in []

  • [[ string1 == string2 ]]: equal in [[]]

  • string1 != string2: not equal

  • string1 =~ regex: regex match

  • -z string1: zero length

  • -n string1: not zero length

a="Linux"
b="macos"

if [[ $a == $b ]]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

if [[ $a =~ .*nux.* ]]; then
    echo "It's there"
fi

for 循环

projects=(p1 p2)
for i in "${projects[@]}"; do
    echo $i '-'
done

Local variable / environment variable

# Only in current shell
name=demo

# Can be accessed by process.env.NODE_ENV in script
export NODE_ENV=production

${}, $()

  • ${var}: 获取并代入变量的值

  • $(command): 执行命令并返回结果

  • `command`: 执行命令并返回结果

Bash function

所有变量(包括函数内)默认是全局变量,除非在函数内用local声明。

Bash Functions | Linuxize

#!/bin/bash

greeting () {
  echo "Hello $1"
}

greeting "Joe"

cd to the path of the script

cd "$(dirname "$0")"

获取 bash 脚本的 arguments

copy.sh -from a.file -to b.file

$# # 4, total number

$0 # copy.sh, script file name

$1 # -from
$2 # a.file
$3 # -to
$4 # b.file

检查是否传递了参数

# 没有传递任何参数
if [ $# -eq 0 ]
    then
        echo "No arguments supplied"
fi

# 没有传递第一个参数
if [ -z "$1" ]
    then
        echo "No argument supplied"
fi

bash: Get OS type

if [[ "$OSTYPE" == "linux-gnu" ]]; then
    # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # ...
fi

os detection - How to detect the OS from a Bash script? - Stack Overflow

zsh tips

You have new mail.

mail

type number ID to read; d 1-9 to delete; x/q to leave.

cd to history

cd -
cd -2
cd -3

cd -<tab>

Bash 批量文件重命名

Rename files in linux

  • Single file

    mv [option] source destination
    
    mv file1.txt file2.txt
    
  • Multiple files with sed regexp

    files="*.wav"
    for f in $files; do
      newname=`echo "$f" | sed 's/[0-9]*//g'`
      mv "$f" "$newname"
    done
    
  • Multiple files

    for f in *.html; do
        mv "$f" "${f%.html}.pug"
    done
    

    ${f%.html} is using the Shell parameter expansion.

    ${f%.html} 匹配末尾, ${f#../ouptput} 匹配开头

  • Multiple files with find

    find . -type f -name "*.html" -exec sh -c 'f="{}"; mv -- "$f" "${f%.html}.pug"' \;
    

Bash 支持换行符

printf 更通用

    printf "hello\nworld"

echo 在不同环境不同版本可能不一致

    echo 'Hello\nworld'
    echo -e "Hello\nworld"
    echo $'Hello\nworld'

出错立即退出脚本

参考

默认情况下 shell 一条命令出错后仍会执行下面的命令,可以通过设置,在出错后立即退出脚本

    set -e

    # commands which fail will cause the script to exit immediately

    bash -e my_script.sh
📖