Skip to main content

Shell

符号作用例子
|把左边命令的输出交给右边命令继续处理ps aux | grep python
>把命令输出写入文件,覆盖文件原内容echo hello > note.txt
>>把命令输出追加到文件末尾echo world >> note.txt
<把文件内容交给命令作为输入sort < names.txt

tips: names.txt > sort 会把 names.txt 当成一个命令来运行,并把它的输出写进名为 sort 的文件。通常会报错


set -euo pipefail
  • -e: 命令失败停止脚本
  • -u: 使用了没定义的变量就报错停止(不当成空字符串)
  • -o pipefail: 一连串 | 连接的命令中 一步失败就整串失败 比如 A | B 默认情况下 Bash 可能只看 B 是否成功;加上 pipefail 后,A 失败也会被发现。

  • ${X:-内容}:X 为空或未设置时,用“内容”替代整个表达式。
  • ${X:+内容}:X 有值时,用“内容”替代整个表达式;否则结果为空。

${...} 是变量展开语法

export PYTHONPATH="$PYTHON_ROOT${PYTHONPATH:+:$PYTHONPATH}"
  • :+ 表示如果前面有值 那么返回后面的
    • A:+B A 非 none 则返回 B

这里就是 PYTHONPATH 非 none 那就返回 :PYTHONPATH

例如,假设:

PYTHON_ROOT=/project/lib
PYTHONPATH=/old/lib

右边展开成:

/project/lib:/old/lib

这个 : 的作用是作为地址的分隔

表示两个搜索目录:

  1. /project/lib
  2. /other/lib

循环

for i in 范围; do
内容
done
for i in $(seq $WAIT -10 10); do
printf "\r %3ds remaining..." "$i"
sleep 10
done
  • $(seq $WAIT -10 10) 生成序列 从wait开始(包括)每次-10 直到10为止
  • \r 回到当前行开头 新数字覆盖上一条倒计时
  • %3d 三个字符宽度显示这里的整数
while [[条件]]; do
内容
done
while [[ $# -gt 0 ]]; do
case "$1" in
--gpu-sam3) GPU_SAM3="$2"; shift 2 ;;
--gpu-graspnet) GPU_GRASPNET="$2"; shift 2 ;;
--gpu-molmo) GPU_MOLMO="$2"; shift 2 ;;
--with-molmo) MOLMO_MODE=true; shift 1 ;;
--no-molmo) MOLMO_MODE=false; shift 1 ;;
--python) PYTHON_BIN="$2"; shift 2 ;;
*) echo "Unknown arg: $1"; exit 1 ;;
esac
done
  • $# 参数个数
  • -gt greater than
  • $2 表示第二个参数
  • shift 2 移除前两个参数
  • ; 分隔同一行两个命令
  • ;; 结束
  • ) 分隔符 结束匹配模式 假设收到参数 --gpu-sam3 0 --no-molmo 编号
$1 $2 $3
--gpu-sam3 0 --no-molmo

当我接收到 --gpu-sam3,然后 GPU_SAM3="$2",拿到 0, 最后直接shift 2 变成

$1
--no-molmo

if [[ -z "$PYTHON_BIN" || ! -x "$PYTHON_BIN" ]]; then
echo "ERROR: no perception Python found."
echo "Set ASPIRE_PERCEPTION_PYTHON or create .venv-libero / .venv-perception / .venv."
exit 1
fi
  • -x 路径是否存在且可执行
  • -z PYTHON_BIN 是否为空
  • exit 1 以错误状态退出

  • () 分组执行,或运行命令并取输出
    • 括号里的命令在一个独立的子 shell 中执行 (cd /tmp && pwd) 不会改变当前终端目录
  • [] 条件判断,或匹配文件名 当然 [[]] 也可以
  • {} 变量展开、命令分组,或生成多个文本
    • ${NAME}
    • { echo first; echo second; }
    • echo file{1,2}.txt 输出 file1.txt file2.txt