-1

I'd like for this Bash script to:

  • read and assign the content of a file to URLS
  • prompt the user to enter a path to download content to, assigning it to PATH
  • iterate through URLS
  • use wget to download the content to PATH.

Here's what I've got so far:

#!/bin/bash
URLS=$(<urls.txt)

read -e -p "Please enter the path of the directory you'd like to save your files to: " PATH

for link in $URLS
do
    wget --background --tries=45 $URLS --directory-prefix $PATH
done
exit 0

My hunch is that I am not using $PATH correctly with wget, as the script will run correctly if I comment out --directory-prefix $PATH.

Thanks in advance for the assistance.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
marshki
  • 175
  • 1
  • 11
  • It's not commenting out `--directory-prefix $PATH` that makes a difference (for purposes of `wget: command not found`), but commenting out `read PATH`. – Charles Duffy Jun 07 '16 at 19:38

1 Answers1

2

PATH is an environment variable with a reserved meaning: It's used to find the location of binaries to execute.

Use a non-reserved name to avoid overwriting it, such as path; this convention is explicitly given in the POSIX specification to avoid overwrite of environment variables with meaning to the system. Quoting with emphasis added:

Environment variable names used by the utilities in the Shell and Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase letters, digits, and the '_' (underscore) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase and lowercase letters shall retain their unique identities and shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.

...which is pertinent even to shell variables which aren't explicitly exported to the environment because assignments to shell variables with names that overlap with an environment variable (such as PATH) implicitly overwrite the latter.


Thus, your code might look like:

#!/bin/bash

read -e -p "Please enter the path of the directory you'd like to save your files to: " path

while IFS= read -r link; do
  wget --background --tries=45 --directory-prefix "$path" "$link"
done <urls.txt

See also:

  • BashFAQ #001, describing best practices around reading a file from bash.
  • DontReadLinesWithFor, explicitly describing caveats around using for to iterate over what's intended to be interpreted as line-oriented data.

Also, note that zsh is not a POSIX-compliant shell; one of the respects in which it diverges from the spirit and intent of the standard is that it gives path special treatment as well, making path not safe as an alternative to PATH if zsh compatibility is needed.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Both the code revision and the thorough explanation are sincerely appreciated. I'm accepting the answer as correct. – marshki Jun 07 '16 at 19:46