Linux中的特殊符号以及特殊语法

辨别||、&&、;、$*等符号在linux中的含义与或# 将&&前后的两个命令当做一个表达式,如果表达式出错,那么可以认为该表达式为false➜ ~ ls / && datebin boot dev etc home initrd.img

辨别||、&&、;、$*等符号在linux中的含义

与或

# 将&&前后的两个命令当做一个表达式,如果表达式出错,那么可以认为该表达式为false
➜  ~ ls / && date
bin  boot  dev  etc  home  initrd.img  initrd.img.old  lastore  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old
Thu Mar 21 14:18:44 HKT 2019

# 第一个命令失败,后面的命令不再执行。短路,因为表达式整体的值已经可以通过第一个表达式获得。
➜  ~ ls /hello && date
ls: cannot access '/hello': No such file or directory

# 与&&恰好相反
➜  ~ ls /hello || date
ls: cannot access '/hello': No such file or directory
Thu Mar 21 14:19:03 HKT 2019

# 第一个执行成功,已经可以获得整个表达式的值,所以不执行第二个表达式。短路。
➜  ~ ls / || date     
bin  boot  dev  etc  home  initrd.img  initrd.img.old  lastore  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old

分号;

表示过程,不计算值,因此按顺序执行。

➜  ~ ls / ; date 
bin  boot  dev  etc  home  initrd.img  initrd.img.old  lastore  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old
Thu Mar 21 14:23:48 HKT 2019
➜  ~ ls /hello ; date
ls: cannot access '/hello': No such file or directory
Thu Mar 21 14:23:52 HKT 2019

$相关表达式

$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, ${10}, ${11}.....指令本身为0。后面为传入参数。个位数的,可直接使用数字,但两位数以上,则必须使用 {} 符号来括住。

#!/bin/bash
echo $#
echo $*
echo $@
echo $0
echo $1
echo $2
echo "--------"
# 当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
for a in $*
do
    echo ${a}
done

for a in $@
do
    echo ${a}
done
echo "--------"
# 但是当它们被双引号" "包含时,就会有区别了:
# "$*"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
# "$@"仍然将每个参数都看作一份数据,彼此之间是独立的。
for a in "$*"
do
    echo ${a} # 这 2 个参数会合并到一起形成一份数据,它们之间是无法分割的
done

for a in "$@"
do
    echo ${a} # 这 2 个参数是相互独立的,它们是 2 份数据
done

输出如下:

➜  Documents ./shell.sh hello world 
2
hello world
hello world
./shell.sh
hello
world
--------
hello
world
hello
world
--------
hello world
hello
world

$? 获取上一个命令的退出状态

➜  ~ pkill -f xxxxoooo
➜  ~ echo $?
1

$!和$$

# Shell最后运行的后台Process的PID 
➜  ~ ping www.baidu.com > /dev/null &
[1] 14025
➜  ~ echo $!
14025

# Shell本身的PID(ProcessID)
➜  ~ ps -ef | grep -v grep | grep zsh 
sasurai   9143  9122  0 09:48 pts/1    00:00:00 /usr/bin/zsh
sasurai  11946  5190  0 14:32 pts/4    00:00:00 /usr/bin/zsh
sasurai  19350 19085  0 10:52 pts/0    00:00:00 /usr/bin/zsh -i
➜  ~ echo $$
9143

输出/输入重导向

文件描述符 名称 常用缩写 默认值
0 标准输入 stdin 键盘
1 标准输出 stdout 屏幕
2 标准错误输出 stderr 屏幕

我们在简单地用<或>时,相当于使用 0< 或 1>(下面会详细介绍)。

  • cmd > file把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。
  • cmd >> file把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件後面。
  • cmd < file使cmd命令从file读入

  • cmd << text从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用<<- ,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。
  • cmd <<< word把word(而不是文件word)和後面的换行作为输入提供给cmd。
  • cmd <> file以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。
  • cmd >| file功能同>,但即便在设置了noclobber时也会复盖file文件,注意用的是|而非一些书中说的!,目前仅在csh中仍沿用>!实现这一功能。
  • : > filename     把文件"filename"截断为0长度.# 如果文件不存在, 那么就创建一个0长度的文件(与'touch'的效果相同).

  • cmd >&n 把输出送到文件描述符n
  • cmd m>&n 把输出 到文件符m的信息重定向到文件描述符n
  • cmd >&- 关闭标准输出
  • cmd <&n 输入来自文件描述符n
  • cmd m<&n m来自文件描述各个n
  • cmd <&- 关闭标准输入
  • cmd <&n- 移动输入文件描述符n而非复制它。(需要解释)
  • cmd >&n- 移动输出文件描述符 n而非复制它。(需要解释) 注意: >&实际上复制了文件描述符,这使得cmd > file 2>&1与cmd 2>&1 >file的效果不一样。

for循环

for var in 集合
do
	cmd1...
done

while循环

while [ 条件 ]
do
    echo "hello"
done

if条件语句

if [ 条件 ]; then
	cmd1
elif [ 条件 ]; then
	cmd2
else
	cmd3
fi

case语句

case 值 in
	模式1)
	    command1
	    command2
	    command3
	    ;;
	模式2)
	    command1
	    command2
	    command3
	    ;;
	*)
	    command1
	    command2
	    command3
	    ;;
esac

Read more

Volcano 与 Kubernetes GPU 调度学习笔记

本笔记系统整理 Volcano 调度器、Kubernetes 调度框架、GPU Device Plugin、HAMi 等云原生 AI 调度领域的核心知识,适合用于学习、复习和工程实践参考。 目录 * 第一部分:Volcano 入门 * 1. Volcano 是什么 * 2. 安装与快速使用 * 3. 核心特性一览 * 第二部分:Volcano 整体架构 * 4. Volcano 解决的核心问题 * 5. 整体架构与数据流 * 6. 三层抽象模型 * 第三部分:Volcano 核心实现原理 * 7. Session 机制 * 8. Gang Scheduling 实现 * 9. Queue 与 DRF 公平调度

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd