TITLE: Bash script to download audio from Youtube DATE: 2024-06-26 AUTHOR: John L. Godlee ==================================================================== This post is actually about a trick I learned that allows bash scripts to accept input either as a string or from stdin. Here is the code. It first checks whether at least one argument is provided to the script. If an argument is found it creates a variable containing all the arguments. If no arguments are found, then it waits for input from stdin, which can either come from a pipe or can be typed in after the script is called. #!/usr/bin/env bash # If argument provided if [ $# -gt 0 ]; then input="$*" else # Read from stdin while IFS= read -r line; do input+="$line" done fi echo $input I used this trick to write a script to download audio files from Youtube using yt-dlp. I wanted to be able to integrate the script with ytfzf, which can search Youtube from the terminal using FZF and optionally print the URL of the selected video. [yt-dlp]: https://github.com/yt-dlp/yt-dlp [ytfzf]: https://ytfzf.github.io/ #!/usr/bin/env sh # Download audio only using yt-dlp # If argument provided if [ $# -gt 0 ]; then input="$*" else # Read from stdin while IFS= read -r line; do input+="$line" done fi # Download yt-dlp \ -f bestaudio \ --extract-audio \ --audio-format m4a \ -S +size,+br \ -o "$PWD/%(title)s.%(ext)s" \ --external-downloader aria2c \ --external-downloader-args "-x 5 -s 5 -j 5 -c -k 1M" $input The script can be called in various ways. Passing an argument: yt_audio https://www.youtube.com/watch?v=Atkp8mklOh0 Using stdin: echo "https://www.youtube.com/watch?v=Atkp8mklOh0" | yt_audio Using stdin with ytfzf: ytfzf -L Terry Barentsen Hotline Cooper Ray | yt_audio With multiple URLs as arguments: yt_audio https://www.youtube.com/watch?v=WyV894c8oqI https://www.youtube.com/watch?v=Atkp8mklOh0 With multiple URLs from stdin: echo "https://www.youtube.com/watch?v=WyV894c8oqI https://www.youtube.com/watch?v=Atkp8mklOh0" | yt_audio