首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash - case语句总是输入默认值。

Bash - case语句总是输入默认值。
EN

Stack Overflow用户
提问于 2021-08-11 10:36:02
回答 2查看 459关注 0票数 3

我正在编写一个Bash脚本来解析CSV文件(由;字符分隔的值)并提取一些参数。根据从文件读取的当前参数,将特定的字符串附加到变量。但是,case语句总是进入默认状态*),我不知道为什么。

我在读取.csv文件时没有问题。已经这样做了,并显示了从文件中读取的参数的输出。一切都很完美。问题是,case语句没有按预期处理。

因此,问题不是读取.csv文件,而是处理case语句中的参数。

这是我的密码:

代码语言:javascript
复制
while IFS=";" read -r arg
do
  case ${arg} in
    "valueX")
      var+="blabla"
      ;;
    "valueY")
      var+="blublu"
      ;;
    *)
      echo -e "Argument ${arg} not supported"
      exit 1
      ;;
  esac
done < filename

假设"valueX“是从文件中读取的当前参数。不知何故,脚本总是输出:

代码语言:javascript
复制
Argument "valueX" not supported

显然,从文件中读取的参数(此处为"valueX")是正确的,但是脚本不会进入相应的状态。相反,无论${arg}持有什么值,它总是进入默认状态。

编辑我认为这将是一个好主意,问这个问题更广泛,但事实证明,这是混淆。下面是完整的bash脚本和.csv文件:

剧本:

代码语言:javascript
复制
#!/bin/bash

# style reset
STYLE_RESET='\e[0m'
# Red foreground color
FOREGROUND_RED='\e[31m'
# Green foreground color
FOREGROUND_GREEN='\e[32m'
# Blue foreground color
FOREGROUND_BLUE='\e[34m'
# Red background color
BACKGROUND_RED='\e[41m'
# Green background color
BACKGROUND_GREEN='\e[42m'
# Blue background color
BACKGROUND_BLUE='\e[44m'

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"


usage()
{
    echo "ToDo"
    exit 1
}
# --------------------------------------- #
# --- Checking Command Line Arguments --- #
# --------------------------------------- #
# Supported command line arguments:
#   -h|--help
#   -a|--address    IP of SSH server for remote VMAF
#   -u|--user       User for SSH server login
#   -d|--doe        DoE worksheet exported as CSV UTF-8 file
PARAMS=""
while (( "$#" )); do
    case "$1" in
        -h|--help)
            usage
            shift
            ;;
        -u|--user)
            if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then # Check length of argument and first character of argument != '-'
                SSH_USER=$2
                shift 2
            else
                echo "Error: Argument for $1 is missing" >&2
                exit 1
            fi
            ;;
        -a|--address)
            if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then # Check length of argument and first character of argument != '-'
                SSH_IP=$2
                shift 2
            else
                echo "Error: Argument for $1 is missing" >&2
                exit 1
            fi
            ;;
        -d|--doe)
            if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then # Check length of argument and first character of argument != '-'
                DOE_FILE=$2
                shift 2
            else
                echo "Error: Argument for $1 is missing" >&2
                exit 1
            fi
            ;;
        -*|--*=) # unsupported flags
            echo "Error: Unsupported flag $1" >&2
            exit 1
            ;;
        *) # DEFAULT
            PARAMS="${PARAMS} $1" # preserve positional arguments
            shift
            ;;
    esac
done
# set positional arguments in their proper place
eval set -- "${PARAMS}"


# ---------------------- #
# --- Processing DoE --- #
# ---------------------- #
echo -e "${BACKGROUND_BLUE}Processing DoE specified in file ${DOE_FILE}:${STYLE_RESET}"
echo -e "${BACKGROUND_BLUE}Configuring Video source for GStreamer pipeline...${STYLE_RESET}"
GSTPIPE_SRC="gst-launch-1.0 -e "
run=1
while IFS=";" read -r motion bitrate_in bitrate_out twopass iframe quantI quantP quantB mvbuffer cabac vbv
do
    echo -e "\n\n${BACKGROUND_BLUE}Setting #${run}:${STYLE_RESET}"
    echo -e "${BACKGROUND_BLUE}${motion} ${bitrate_in} ${bitrate_out} ${twopass} ${iframe} ${quantI} ${quantP} ${quantB} ${mvbuffer} ${cabac} ${vbv}${STYLE_RESET}"
    echo -e "\n${BACKGROUND_BLUE}Generating GStreamer pipelines...${STYLE_RESET}"

    case ${motion} in
        "low")
            GSTPIPE_SRC+="videotestsrc pattern=colors num-buffers=300 ! " # -> no motion content
            case ${bitrate_in} in   # -> bitrate of video source (width*height*framerate)
                "low") # -> 640x480
                    GSTPIPE_SRC+="'video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)I420' "
                    width=640
                    height=480
                    fps=30
                    ;;
                "high") # -> 3840x2160
                    GSTPIPE_SRC+="'video/x-raw, width=(int)3840, height=(int)2160, framerate=(fraction)30/1, format=(string)I420' "
                    width=3840
                    height=2160
                    fps=30
                    ;;
                *)
                    echo -e "\n\n${BACKGROUND_RED}Input bitrate ${bitrate_in} not supported${STYLE_RESET}"
                    echo -e "Use low, or high instead"
                    exit 1
                    ;;
            esac
            ;;
        "high")
            GSTPIPE_SRC+="filesrc location=${SCRIPT_DIR}/extensive.mp4 " # -> high motion content
            case ${bitrate_in} in   # -> bitrate of video source (width*height*framerate)
                "low") # -> 640x480
                    GSTPIPE_SRC+="blocksize=460800 ! " # blocksize=width*height*bytesPerPixel (I420->12bit->bytesPerPixel=1.5)
                    GSTPIPE_SRC+="'video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)I420' "
                    width=640
                    height=480
                    fps=30
                    ;;
                "high") # -> 3840x2160
                    GSTPIPE_SRC+="blocksize=12441600 ! " # blocksize=width*height*bytesPerPixel (I420->12bit->bytesPerPixel=1.5)
                    GSTPIPE_SRC+="'video/x-raw, width=(int)3840, height=(int)2160, framerate=(fraction)30/1, format=(string)I420' "
                    width=3840
                    height=2160
                    fps=30
                    ;;
                *)
                    echo -e "\n\n${BACKGROUND_RED}Input bitrate ${bitrate_in} not supported${STYLE_RESET}"
                    echo -e "Use low, or high instead"
                    exit 1
                    ;;
            esac
            ;;
        *)
            echo -e "${BACKGROUND_RED}Argument ${motion} for DoE factor 'motion' not supported${STYLE_RESET}"
            echo -e "Use low, or high instead"
            exit 1
            ;;
    esac

    GSTPIPE_ENC=$GSTPIPE_SRC
    GSTPIPE_REF=$GSTPIPE_SRC

    GSTPIPE_REF+="! y4menc ! filesink location=${SCRIPT_DIR}/reference${fps}fps_run${run}.y4m"

    GSTPIPE_ENC+="! nvvidconv ! 'video/x-raw(memory:NVMM)' ! nvv4l2h264enc "
    GSTPIPE_ENC+="bitrate=${bitrate_out} EnableTwopassCBR=${twopass} "
    case ${iframe} in
        "low")
            GSTPIPE_ENC+="iframeinterval=20 SliceIntraRefreshInterval=10 "
            ;;
        "high")
            GSTPIPE_ENC+="iframeinterval=120 SliceIntraRefreshInterval=60 "
            ;;
        *)
            echo -e "${BACKGROUND_RED}Argument ${motion} for DoE factor iframe is not supported${STYLE_RESET}"
            echo -e "Use low, or high instead"
            exit 1
            ;;
    esac
    # The range of B frames does not take effect if the number of B frames is 0. (https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/accelerated_gstreamer.html#wwpID0E0YX0HA)
    GSTPIPE_ENC+="quant-i-frames=${quantI} quant-p-frames=${quantP} quant-b-frames=${quantB} num-b-frames=1 EnableMVBufferMeta=${mvbuffer} cabac-entropy-coding=${cabac} "
    GSTPIPE_ENC+="! nvv4l2decoder ! nvvidconv ! 'video/x-raw' ! y4menc ! filesink location=${SCRIPT_DIR}/distorted${fps}fps_run${run}.y4m"
    echo -e "${BACKGROUND_BLUE}Distorted Video:${STYLE_RESET}"
    echo -e "${FOREGROUND_BLUE}${GSTPIPE_ENC}${STYLE_RESET}"
    echo -e "${BACKGROUND_BLUE}Reference Video:${STYLE_RESET}"
    echo -e "${FOREGROUND_BLUE}${GSTPIPE_REF}${STYLE_RESET}"

    # --- Launching GStreamer pipelines (surpress detailed output) --- #
    echo -e "${BACKGROUND_BLUE}Launching GStreamer pipeline for encoded video (distorted):${STYLE_RESET}"
    eval "${GSTPIPE_ENC[@]}" #> /dev/null
    echo -e "${BACKGROUND_BLUE}Launching GStreamer pipeline for uncompressed video (reference):${STYLE_RESET}"
    eval "${GSTPIPE_REF[@]}" #> /dev/null

    # --- Create and Check Remote Directories --- #
    echo -e "\n${BACKGROUND_BLUE}Video transfer to remote machine:${STYLE_RESET}"
    SSH_DIR_ADD="v4l2h264/motion_${motion}/bitrate_${bitrate_in}/"
    SSH_DIR="/home/${SSH_USER}/metrics/${SSH_DIR_ADD}"  # Create variable holding path of directory for both:
                                                    #   1.) reference.y4m and distorted.y4m videos
                                                    #   2.) remote VMAF
    ssh ${SSH_USER}@${SSH_IP} "test -d ${SSH_DIR}" < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash
    if [ $? -ne 0 ]; then # Directory does not exist
        echo -e "${BACKGROUND_BLUE}Creating remote directory for run #${run}: ${SSH_DIR}...${STYLE_RESET}"
        ssh ${SSH_USER}@${SSH_IP} "mkdir -p ${SSH_DIR}" < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash
    else # Directory already exists
        echo -e "${BACKGROUND_BLUE}Remote directory ${SSH_DIR} already exists${STYLE_RESET}"
    fi

    # --- Transfer Video Files --- #
    echo -e "${BACKGROUND_BLUE}Transfering reference and distorted videos of run #${run}:${STYLE_RESET}"
    scp ${SCRIPT_DIR}/distorted${fps}fps_run${run}.y4m ${SSH_USER}@${SSH_IP}:${SSH_DIR} < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash
    scp ${SCRIPT_DIR}/reference${fps}fps_run${run}.y4m ${SSH_USER}@${SSH_IP}:${SSH_DIR} < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash

    # --- Run VMAF on Remote Machine --- #
    echo -e "\n${BACKGROUND_BLUE}Running VMAF metric for DoE run #${run} on remote machine...${STYLE_RESET}"
    ssh ${SSH_USER}@${SSH_IP} "vmaf -r ${SSH_DIR}/reference${fps}fps_run${run}.y4m -d ${SSH_DIR}/distorted${fps}fps_run${run}.y4m -w ${width} -h ${height} -p 420 -b 12 -o ${SSH_DIR}/log${fps}fps_run${run}.xml --threads 8" < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash
    echo -e "${BACKGROUND_BLUE}VMAF metric for DoE run #${run} finished.${STYLE_RESET}"

    # --- Remove Videos on Remote Machine (Laptop) --- #
    echo -e "\n${BACKGROUND_BLUE}Removing videos from remote machine${STYLE_RESET}"
    ssh ${SSH_USER}@${SSH_IP} "rm ${SSH_DIR}/distorted${fps}fps_run${run}.y4m ${SSH_DIR}/reference${fps}fps_run${run}.y4m" < /dev/null # see https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash

    # --- Remove videos on local machine (SPU) --- #
    echo -e "\n${BACKGROUND_BLUE}Removing videos from local machine${STYLE_RESET}"
    rm distorted${fps}fps_run${run}.y4m reference${fps}fps_run${run}.y4m

    ((run++))

done < <(cut -d ";" -f5,6,7,8,9,10,11,12,13,14,15,16 ${DOE_FILE} | tail -n +2) # read from the second line of the file (no header) and only read the columns specified with -f
((run--))

exit 0

.csv文件:

代码语言:javascript
复制
"StdOrder";"RunOrder";"CenterPt";"Blocks";"motion";"bitrate_in";"bitrate_out";"twopass";"iframe";"quantI";"quantP";"quantB";"mvbuffer";"cabac"
1;1;1;1;"low";"low";200000;"false";"low";0;0;0;"true";"true"
6;2;1;1;"high";"low";80000000;"false";"low";51;0;51;"true";"false"
8;3;1;1;"high";"high";80000000;"false";"high";0;0;0;"false";"true"
2;4;1;1;"high";"low";200000;"false";"high";0;51;51;"false";"false"
3;5;1;1;"low";"high";200000;"false";"high";51;0;51;"false";"false"
7;6;1;1;"low";"high";80000000;"false";"low";0;51;51;"true";"false"
10;7;1;1;"high";"low";200000;"true";"high";51;0;0;"true";"false"
9;8;1;1;"low";"low";200000;"true";"low";51;51;51;"false";"true"
4;9;1;1;"high";"high";200000;"false";"low";51;51;0;"true";"true"
13;10;1;1;"low";"low";80000000;"true";"high";0;0;51;"true";"true"
5;11;1;1;"low";"low";80000000;"false";"high";51;51;0;"false";"true"
12;12;1;1;"high";"high";200000;"true";"low";0;0;51;"false";"true"
15;13;1;1;"low";"high";80000000;"true";"low";51;0;0;"false";"false"
14;14;1;1;"high";"low";80000000;"true";"low";0;51;0;"false";"false"
16;15;1;1;"high";"high";80000000;"true";"high";51;51;51;"true";"true"
11;16;1;1;"low";"high";200000;"true";"high";0;51;0;"true";"false"
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-11 11:07:31

显然,从文件中读取的参数(此处为"valueX")是正确的。

由于您认为引号是参数的一部分是正确的,为了将它们与case模式匹配,您必须转义模式引号:

代码语言:javascript
复制
  case ${arg} in
    \"valueX\")

有趣的是,这似乎是一个Bash (文档)错误,因为这只说明:

每个模式都经历了倾斜扩展、参数扩展、命令替换和算术扩展。

这并不能说明这个模式会被移除。

票数 3
EN

Stack Overflow用户

发布于 2021-08-11 11:15:13

您的示例数据中没有一个包含valueX,但假设您在第五个字段中寻找"high",则需要要求shell拆分为至少六个字段;

代码语言:javascript
复制
while IFS=";" read -r _first _second _third _fourth arg _rest
do
  case ${arg} in
    '"high"')
      var+="blabla"
      ;;
    '"low"')
      var+="blublu"
      ;;
    *)
      echo -e "Argument ${arg} not supported"
      exit 1
      ;;
  esac
done < filename

不过,这里一个更好的解决方案可能是使用Awk。

代码语言:javascript
复制
awk -F ';' '$5 !~ /"(high|low)"/ { print "Argument " $5 " is not supported" }' filename

如果没有脚本的其余部分,就很难判断应该朝哪个方向继续下去;通常,如果您无论如何都在使用Awk,那么在Awk中实现其余的逻辑也是有意义的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68740361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档