Bash

Bash

Bash / sh

#!/bin/sh

#!/bin/bash

Startup scripts

  • interactive login: /etc/profile (system) -> ~/.bash_profile 或 ~/.profile (先找到的)
  • none-interactive login: /etc/bash.bashrc (部分系统) -> ~/.bashrc
    • none-interactive login 示例: systemd / init.d 启动脚本环境;其他机器通过 ssh host command 在本机上执行命令;cron job。

通常习惯默认在 ~/.bash_profile 里调用 ~/.bashrc :

if [ -f ~/.bashrc ]; then
        source ~/.bashrc
fi

注意某些系统(如 Ubuntu)默认的 ~/.bashrc 内容直接禁止了 none-interactive login 时运行该脚本内容:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

需要把这行去掉。

Cheatsheet

If

if [ "$INTERFACE" != "pppoe-wan" ]
then
        exit
fi
  • Operator: =, !=
  • Logic operator : -a (and), -o (or)
  • number compare : -lt, -gt, -le, -ge, -eq

Check String starts with

word="appel"

if [[ $word = a* ]]
then
  echo "Starts with a"
else
  echo "No match"
fi

Switch

# This script does a very simple test for checking disk space.

space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -`

case $space in
[1-6]*)
  Message="All is quiet."
  ;;
[7-8]*)
  Message="Start thinking about cleaning out some stuff.  There's a partition that is $space % full."
  ;;
9[1-8])
  Message="Better hurry with that new disk...  One partition is $space % full."
  ;;
99)
  Message="I'm drowning here!  There's a partition at $space %!"
  ;;
*)
  Message="I seem to be running with an nonexistent amount of disk space..."
  ;;
esac

Variables

FOO="${VARIABLE:-default}"  # If variable not set or null, use default.
FOO="${VARIABLE:=default}"  # If variable not set or null, set it to default.
  • "${var%A Suffix}", "${PWD%/}", "${PWD%%/}" : Expand the value contained within the parameter var after removing the string A Suffix from the end of it. Works just like the prefix trimming operation, only takes away from the end.
    • ${0%/*} : 当前运行的 bash 脚本($0)所在目录。
  • "${var#A Prefix}", "${PWD#/}", "${PWD##/}" : Expand the value contained within the parameter var after removing the string A Prefix from the beginning of it. If the value doesn't have the given prefix, it is expanded as is. The prefix can also be a glob pattern, in which case the string that matches the pattern is removed from the front. You can double the # mark to make the pattern match greedy.

split string

Only available in bash (not sh)

IN="bla@some.com;john@home.com"
arrIN=(${IN//;/ })
echo ${arrIN[1]}   # Output: john@home.com

This construction replaces all occurrences of ';' (the initial // means global replace) in the string IN with ' ' (a single space), then interprets the space-delimited string as an array (that's what the surrounding parentheses do).

The syntax used inside of the curly braces to replace each ';' character with a ' ' character is called Parameter Expansion.

There are some common gotchas:

  • If the original string has spaces, you will need to use IFS:
    IFS=':'; arrIN=($IN); unset IFS;
  • If the original string has spaces and the delimiter is a new line, you can set IFS with:
    IFS=$'\n'; arrIN=($IN); unset IFS;

Tips

Output binary data

# Only work in bash. DO NOT work in sh!
echo -n -e '\x01\x02' > file

fg error "bash:no job control in this shell"

You may need to enable job control:

#! /bin/bash   
set -m

cd "pwd" of script self file

参考这里

cd "${0%/*}"

or

SCRIPT_PATH=${0%/*}
if [ "$0" != "$SCRIPT_PATH" ] && [ "$SCRIPT_PATH" != "" ]; then 
    cd $SCRIPT_PATH
fi

Last update: 2023-10-26 06:48:17 UTC