大数据

shell 知识点回顾

sh01

#!/usr/bin/env bash
set -Eeuo pipefail

# 1、默认值演示
echo "=== 默认值演示 ==="
NAME="${NAME:-World}"
echo "Hello, $NAME!"

# 2、位置参数演示
echo "=== 位置参数 ==="
echo "脚本名称:$0"
echo "第一个参数:${1:-未提供}"
echo "第二个参数:${2:-未提供}"
echo "所有参数:$@"
echo "参数个数:$#"

# 3、带默认只的参数
INPUT_DIR="${1:-/tmp/default_input}"
OUTPUT_DIR="${2:-/tmp/default_output}"
echo "输入目录:$INPUT_DIR"
echo "输出目录:$OUTPUT_DIR"

# 4、检查参数
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
  echo "Usage: $0 [input_dir] [output_dir]"
  exit 0
fi

echo "脚本执行完成!"

sh02

#!/usr/bin/env bash
set -Eeuo pipefail
# 测试-u:注释下面变量再运行会直接报错
TEST_VAR="hello"
echo $TEST_VAR
# 测试-e:注释set后执行不会退出,开启后直接终止
ls /nonexistent_dir
echo "这句不会打印"

sh03

#!/usr/bin/env bash
set -Eeuo pipefail

NAME="${NAME:-guest}"
echo "名字:$NAME"

# 外部覆盖测试 终端执行 NAME=bob ./sh03.sh

# 扩展:?必填校验
INPUT_DIR="${INPUT_DIR:?必须传入INPUT_DIR环境变量}"
echo $INPUT_DIR

sh04

#!/usr/bin/env bash
set -Eeuo pipefail

NOW=$(date +%Y%m%d_%H%M%S)
PID=$$
UNIQUE_NAME="task_${NOW}_$PID"
echo "唯一名称:$UNIQUE_NAME"
echo "当前脚本PID:$PID"

sh05

#!/usr/bin/env bash
set -Eeuo pipefail

usage() {
  cat <<'HELP'
脚本用法:
  ./sh05.sh [参数1] [参数2]
  -h/--help 查看帮助
HELP
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  usage
  exit 0
fi

echo "第一个参数:${1:-无}"

sh06

#!/usr/bin/env bash
set -Eeuo pipefail

echo "总参数个数:$#"
echo "脚本名:$0"

first="${1:-默认路径}"
if [[ $# -gt 0 ]]; then shift; fi
second="${1:-默认输出}"
if [[ $# -gt 0 ]]; then shift; fi

echo "入参1: $first"
echo "入参2:$second"
echo "剩余额外参数:"
for p in "$@"; do
  echo "- $p"
done

sh07

#!/usr/bin/env bash
set -Eeuo pipefail

check_bin() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "错误:未安装 $1" >&2
    exit 127
  fi
  echo "检测到 $1:$(command -v "$1")"
}

check_bin curl
check_bin docker

sh08

#!/usr/bin/env bash
set -Eeuo pipefail

absolute_path() {
  local path="$1"
  # 通配符 以/开头
  if [[ "$path" == /* ]]; then
    echo "$path"
  else
    echo "${PWD}/${path}"
  fi
}

echo $(absolute_path "./test")
echo $(absolute_path "/opt/data")

sh09

#!/usr/bin/env bash
set -Eeuo pipefail

TEST_DIR="./test_out/subdir"
if [[ ! -d "$TEST_DIR" ]]; then
  echo "目录不存在,创建"
  mkdir -p $TEST_DIR
fi
touch "$TEST_DIR/demo.txt"
if [[ -f "$TEST_DIR/demo.txt" ]]; then
  echo "文件创建成功"
fi

sh10

#!/usr/bin/env bash
set -Eeuo pipefail

clean() {
  echo -e "\n脚本退出,执行清理工作"
}
trap clean EXIT INT TERM
echo "按Ctrl+C测试捕获,或等待结束"
sleep 10

sh11

#!/usr/bin/env bash
set -Eeuo pipefail

cmd=(echo "开始执行")
cmd+=("第一个参数")
cmd+=("带 空格 的路径")
"${cmd[@]}"

sh12

#!/usr/bin/env bash
set -Eeuo pipefail

NAME="Shell传入的值"
NUM=100
NAME="$NAME" NUM="$NUM" python3 - << 'PY'
import os
print("Python接收变量:", os.environ["NAME"], os.environ["NUM"])
PY

sh13

#!/usr/bin/env bash
set -Eeuo pipefail

echo "$0 $1 $2"
echo $*
echo $#
echo $@

for p in "$@"; do
  echo "$p"
done

sh14

#!/usr/bin/env bash
set -Eeuo pipefail

echo $[1+1]
echo $((1+1))
expr 1 + 1
expr `expr 2 + 3` \* 4
echo $[(2+3)*4]

[ 1 -lt 0 ] && echo OK || echo Fail

基础语法

sh01

#!/usr/bin/env bash
set -Eeuo pipefail

if [ $1 -eq 1 ]; then
    echo "eq 1"
elif [ $1 -eq 2 ]; then
    echo "eq 2"
fi

sh02

#!/usr/bin/env bash
set -Eeuo pipefail

case $1 in
  "a")
    echo "a 1"
    ;;
  "b")
    echo "b 2"
    ;;
  "c")
    echo "c 3"
    ;;
  "d")
    echo "d 4"
    ;;
  *)
    echo "other"
    ;;
esac

sh03

#!/usr/bin/env bash
set -Eeuo pipefail

res=0

for ((i=0;i<$1;i++))
  do
    res=$((res + i))
  done
echo $res

sh04

#!/usr/bin/env bash
set -Eeuo pipefail

while [ $# -gt 0 ]; do
    echo "参数:${1}"
    shift
done

sh05

#!/usr/bin/env bash
set -Eeuo pipefail

read -t 5 -p "Enter your name:" NAME
echo $NAME

sh06

#!/usr/bin/env bash
set -Eeuo pipefail

sum() {
    s=0
    s=$(($1 + $2))
    echo "s: $s"
    return $s
}

read -p "input n1: " p1
read -p "input n2: " p2

sum p1 p2

sh07

#!/usr/bin/env bash
set -Eeuo pipefail

i=1

cat > cutdemo.txt << EOF
hello$i spark
hello2 java
hello3 hadoop
EOF

cut -d " " -f 1 cutdemo.txt

ifconfig eth0 | grep netmask | cut -d " " -f 10

sh08

#!/usr/bin/env bash
set -Eeuo pipefail

sed "2a hello kafka" demo.txt
echo "----------"
sed "/spark/d" demo.txt
echo "----------"
sed "s/spark/yarn/g" demo.txt
echo "----------"
sed -e "3d" -e "s/spark/yarn/g" demo.txt

sh09

#!/usr/bin/env bash
set -Eeuo pipefail

# cp /etc/passwd ./
awk -F : '/^root/ {print $7}' passwd
awk -F : '/^root/ {print $1","$7}' passwd
awk -F : 'BEGIN{print "user,shell"} END{print "last"}' passwd
# 统计passwd文件名 每行的行号 每行的列数
awk -F : '{print "filename: " FILENAME ", linenumber: " NR ", columns: " NF}' passwd
# 查询文本中空行所在的行号
awk '/^$/ {print NR}' passwd

sh10

#!/usr/bin/env bash
set -Eeuo pipefail

sort -t : -k 3 sortdemo.txt

sh11

#!/usr/bin/env bash
set -Eeuo pipefail

for file in `ls`
  do
    echo "$file"
  done

echo $$

补充

args

#!/usr/bin/env bash
set -Eeuo pipefail

echo "脚本名:$0"
echo "参数个数:$#"
echo "第一个参数:${1:-无}"
echo "第二个参数:${2:-无}"
echo "所有参数:$@"


echo "使用shift获取"
echo "第一个参数:${1:-无}"
echo "参数个数:$#"
echo "所有参数:$@"
echo "执行shift"
shift
echo "第一个参数:${1:-无}"
echo "参数个数:$#"
echo "所有参数:$@"

f01

#!/usr/bin/env bash
set -Eeuo pipefail

require_cmd() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "Missing required command: $1" >&2
    exit 127
  fi
}

require_cmd python
require_cmd docker

f02

#!/usr/bin/env bash
set -Eeuo pipefail

absolute_path() {
  local path="$1"
  if [[ "$path" == /* ]]; then
    printf '%s' "$path"
  else
    printf '%s/%s' "$PWD" "$path"
  fi
}

absolute_path "$1"

f03

#!/usr/bin/env bash

clean_container() {
  echo "清理中..."
}

# 只捕获 EXIT,不捕获 INT
trap clean_container EXIT

echo "程序执行中..."
sleep 10
echo "正常退出"

py

#!/usr/bin/env bash
set -Eeuo pipefail

NAME="bob" python3 <<'PY'
import os
name = os.environ.get("NAME", "tom")
age = os.environ.get("AGE", 18)
print(name, age)
PY