You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本read命令被跳过,vformat变量无法获取值求解决

Bash脚本read命令被跳过,vformat无法获取输入值

脚本运行时read命令直接跳过,vformat变量无法获取用户输入,以下是问题分析和解决办法:

问题相关信息

示例视频

YouTube视频:https://www.youtube.com/watch?v=TqOeMYtOc1w

脚本代码

# Color
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\[\033[0;34m\]'
NC='\033[0m' # No Color

function red {
    printf "${RED}$@${NC}\n"
}

function green {
    printf "${GREEN}$@${NC}\n"
}

function yellow {
    printf "${YELLOW}$@${NC}\n"
}

function blue {
    printf "${BLUE}$@${NC}\n"
}

# echo $(red apple) $(yellow banana)

echo $(red "Enter url:")
read url

# echo "$url"
url="https:${url##*https:}"
# url=$(echo "$url" | egrep -o 'https?://[^ ")]+')

allFormat=$(youtube-dl -F "$url")
echo "$allFormat"

echo $(blue "\nEnter format to download video:")
read vformat

echo $(green "Enter directory to download:")
read -r dpath

echo $(green "Enter start time to skip the video in s:")
read stime

title=$(youtube-dl --get-title "$url")
# echo "$title"

mod_title=$(echo "$title" | tr ' ' '_' | tr ':' '@')

echo $vformat

l=$(youtube-dl -f "${vformat:-18}" --verbose --newline -o "$dpath/$mod_title/$title.mp4" "$url" | grep --line-buffered -oP '^\[download\].*?\K([0-9.]+\%|#\d+ of \d)' |
    zenity --progress \
    --width=400 \
  --title="Downloading youtube video" \
  --text="Downloading..." \
  --percentage=0)
echo "$l"

问题截图

脚本跳过read命令的运行截图


问题原因

  1. 颜色变量错误:BLUE变量中的\[\]是Bash提示符(PS1)专用的转义标记,用于告诉终端忽略这部分字符的长度计算,在普通printf输出中会导致终端输出混乱,干扰后续的交互输入。
  2. 冗余的echo包裹:echo $(red "xxx")这种写法会创建子shell执行red函数,多余的处理可能导致终端状态异常,而且red函数本身已经通过printf输出了带换行的内容,不需要再用echo包裹。

解决办法

1. 修复颜色变量

将BLUE='\[\033[0;34m\]'修改为:

BLUE='\033[0;34m'

2. 简化提示输出方式

直接调用颜色函数输出提示信息,去掉多余的echo包裹:

# 原写法
# echo $(red "Enter url:")
# 修改为
red "Enter url:"
read url

# 原写法
# echo $(blue "\nEnter format to download video:")
# 修改为
blue "\nEnter format to download video:"
read vformat

# 同理修改其他提示输出
green "Enter directory to download:"
read -r dpath

green "Enter start time to skip the video in s:"
read stime

3. 可选:隔离命令的标准输入

如果youtube-dl命令意外占用了标准输入(概率较低),可以在命令后追加< /dev/null,强制命令不从stdin读取内容:

allFormat=$(youtube-dl -F "$url" < /dev/null)
title=$(youtube-dl --get-title "$url" < /dev/null)

完成以上修改后,read命令就能正常等待用户输入,vformat变量也能正确获取值。


内容的提问来源于stack exchange,提问作者Pygirl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:52:37