입력 URL이 제공되지 않으면 텍스트 파일의 목록이 사용됩니다.

입력 URL이 제공되지 않으면 텍스트 파일의 목록이 사용됩니다.

명령줄에서 URL을 입력으로 사용하거나 입력이 제공되지 않으면 내부 목록을 사용하는 yt-dlp용 셸 스크립트를 만들려고 합니다. 입력이 주어지면 스크립트가 작동하지만 입력이 주어지지 않으면 충돌이 발생하므로 내부 목록을 사용합니다.

#!/usr/bin/env bash

URLfromTerminal="$1"
PathToList="--batch-file '${HOME}/bin/ytdlp/Lists/Test.txt'"

[[ -z "$URLfromTerminal" ]] && Download="$PathToList" || Download="$URLfromTerminal"

yt-dlp -ciw \
  -S "res:1920" \
  --ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
  "$Download"

입력이 제공되지 않고 내부 목록이 사용될 때 오류 메시지:

yt-dlp: error: no such option: --batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'

변수에서 확장할 때 yt-dlp가 텍스트 파일 경로를 옵션으로 간주하는 이유는 무엇입니까?

저는 쉘 스크립팅을 처음 접했고 모범 사례가 무엇인지 모르기 때문에 일반적인 개선도 환영합니다.

답변1

귀하의 질문에는 두 가지 측면이 있습니다.

  1. 파일 이름을 보유하는 것으로 간주되는 문자열에 리터럴 따옴표를 포함합니다. 따옴표는 파일 이름의 일부가 아니므로 문자열에 포함되어서는 안 됩니다.
  2. --batch-file파일 경로 이름이 포함된 문자열에 이 옵션을 포함할 수 있습니다. 이렇게 하면 인용되지 않은 변수 확장을 적절하게 분할하기 위해 쉘에 의존하게 됩니다. 인용한 확장으로 인해 $Download쉘은 문자열을 분할하지 않으며 전체 문자열이 단일 인수로 사용됩니다.

#!/bin/sh

if [ -n "$1" ]; then
    printf '%s\n' "$1"
else
    cat ~/bin/ytdlp/Lists/Test.txt
fi |
yt-dlp -ciw \
  -S res:1920 \
  --ffmpeg-location ~/bin/ffmpeg/ffmpeg \
  -a -

이는 첫 번째 매개변수가 비어 있는지 확인하기 위해 간단한 테스트를 사용합니다 -n. 비어 있지 않으면 printf(same as) 을 사용하여 읽을 대상 으로 전달합니다 yt-dlp. 비어 있으면 텍스트 파일이 전달됩니다.-a ---batch-file -yt-dlpcat


시도하는 것과 더 유사한 방식으로 문제를 해결하십시오.

#!/bin/sh

if [ -z "$1" ]; then
    set -- -a ~/bin/ytdlp/Lists/Test.txt
fi

yt-dlp -ciw \
  -S res:1920 \
  --ffmpeg-location ~/bin/ffmpeg/ffmpeg \
  "$@"

이는 비어 있지 않은 yt-dlp경우 스크립트의 인수 목록을 전달합니다 . $1그렇지 않으면 사용하기 전에 인수 목록을 -a텍스트 파일의 경로 이름 으로 설정합니다.저것통화 yt-dlp.

이렇게 하면 스크립트의 명령줄에 URL뿐만 아니라 원하는 만큼의 추가 인수를 전달할 수 있습니다.

답변2

당신이 인용한 내용을 보세요! 두 개의 매개변수 문자열을 전달하려고 합니다.

--batch-file

그리고

'/Users/UserName/bin/ytdlp/Lists/Test.txt'

주장으로는,

"--batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'"

예를 들어, yt-dlp는 호출 매개변수에 대해 알고 있지만(즉, 매개변수 문자열을 해석하는 방법을 알고 있지만) --batch-file그렇지 --help않습니다 --batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'.

마지막 줄은 감싸지 않았습니다 ".$Download

답변3

일반적으로더 안전하고 더 나은도착하다쉘 변수 인용. 그러나 이 경우 따옴표 "--batch-file '${HOME}/bin/ytdlp/Lists/Test.txt'"는 플래그 및 해당 값이 아닌 단일 인수로 전달되므로 스크립트를 손상시키는 것은 따옴표입니다 . 임의의 파일 이름을 사용할 수 있는 가장 간단한 솔루션은 옵션이 아닌 변수에 경로를 입력하는 것입니다.

#!/usr/bin/env bash

URLfromTerminal="$1"
PathToList="$HOME/bin/ytdlp/Lists/Test.txt"

if [[ -z "$URLfromTerminal" ]]; then
    DownloadFlag="--batch-file"
    DownloadPath="$PathToList"
else
    DownloadPath="$URLfromTerminal"
fi

yt-dlp -ciw \
  -S "res:1920" \
  --ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
  "$DownloadFlag" "$DownloadPath"

비어 있으면 $DownloadFlag단순히 빈 문자열로 전달되므로 명령은 계속 작동합니다.


공백이 포함된 매개변수를 전달하는 안전한 표준 방법은 배열을 사용하는 것입니다. 따라서 더 복잡한 경우에는 다음이 필요하므로 해당 옵션도 살펴보는 것이 좋습니다.

#!/usr/bin/env bash

URLfromTerminal="$1"
PathToList="$HOME/bin/ytdlp/Lists/Test.txt"

if [[ -z "$URLfromTerminal" ]]; then
    DownloadPath=( "--batch-file" "$PathToList")
else
    DownloadPath=( "$URLfromTerminal" )
fi

yt-dlp -ciw \
  -S "res:1920" \
  --ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
  "${DownloadPath[@]}"

관련 정보