AI模型容器化部署实战
2026/1/8 2:12:11
命令替换= 把一个命令的输出作为另一个命令的参数或变量值。这是Shell编程中最强大、最常用的功能之一!
# 两种语法都有效`command`# 反引号(传统)$(command)# $() 语法(现代,推荐)# 传统反引号echo"Today is`date`"# 现代 $() 语法echo"Today is$(date)"# 输出:# Today is Wed Jan 1 12:00:00 EST 2023输入: echo "File count: $(ls | wc -l)" ↓ 1. 执行命令替换: $(ls | wc -l) → "5" ↓ 2. 替换后: echo "File count: 5" ↓ 3. 执行: 输出 "File count: 5"// Shell内部的简化流程char*command="echo $(date)";// 1. 解析:找到 $(date)// 2. 创建子进程执行 date// 3. 捕获输出:"Wed Jan 1 12:00:00"// 4. 替换:echo Wed Jan 1 12:00:00// 5. 执行最终命令# 把命令输出保存到变量files_count=$(ls-1|wc-l)current_user=$(whoami)system_uptime=$(uptime-p)echo"User:$current_user, Files:$files_count"echo"System$system_uptime"# 基于日期创建文件名backup_name="backup-$(date+%Y%m%d).tar.gz"log_file="/var/log/app-$(date+%F).log"echo"Creating$backup_name"tar-czf$backup_name/data/# 对每个.txt文件进行操作forfilein$(ls*.txt);doecho"Processing$file"# 处理文件...done# 更安全的版本(处理含空格文件名)whileIFS=read-rfile;doecho"Processing:$file"done<<(find.-name"*.txt")# 检查服务是否运行if[$(pgrep nginx|wc-l)-gt0];thenecho"Nginx is running"elseecho"Starting nginx..."servicenginx startfi# 嵌套使用total_size=$(du-sh$(find.-name"*.log")|tail-1|awk'{print $1}')echo"Total log size:$total_size"# 相当于:# 1. $(find . -name "*.log") → 列出所有.log文件# 2. du -sh [文件列表] → 计算总大小# 3. tail -1 | awk '{print $1}' → 提取大小值$( )vs.` `对比| 特性 | $(command) | `command` |
|---|---|---|
| 可读性 | 更好,清晰 | 较差,易混淆 |
| 嵌套 | 容易:$(echo $(whoami)) | 困难:需要转义 |
| 错误处理 | 更清晰 | 容易出错 |
| 现代Shell | 推荐 | 遗留用法 |
| 与单引号区分 | 容易 | 困难(’ vs `) |
# $( ) 嵌套 - 清晰result=$(echo"Hello$(whoami)")# 反引号嵌套 - 需要转义,混乱!result=`echo"Hello\`whoami\`"`# ❌ 错误:多余空格files="$(ls)"# 如果文件有换行,会变成多行echo$files# 所有文件挤在一行!# ✅ 正确:使用数组files=($(ls))# 转为数组echo"${files[@]}"# 保持原有分行# ❌ 文件名包含特殊字符时forfilein$(ls);dorm"$file"# 如果文件名是 "my file.txt",会被当成两个文件!done# ✅ 使用 find + while readfind.-maxdepth1-type f|whileIFS=read-rfile;dorm"$file"done# ❌ 在循环中重复执行foriin{1..100};docount=$(find/ -name"*.conf"|wc-l)# 每次循环都执行find!done# ✅ 先计算一次count=$(find/ -name"*.conf"|wc-l)foriin{1..100};doecho"Count:$count"done