0
votes

The below script download file using CURL, I'm trying inside the loop to save the file and also to insert the saved file name into a variable and then to print it.

My script downloads the script and saved the file but can't echo the saved file name:

for link in $url2; do
    cd /var/script/twitter/html_files/ && file1=$({ curl -O $link ; cd -; })
    echo $file1
done

Script explanation:

$url2 contains one or more URLs

curl -O write output to a file named as the remote file

1

1 Answers

2
votes

Your code has several problems. Assuming $url2 is a list of valid URLs which do not require shell quoting, you can make curl print the output variable directly.

cd /var/script/twitter/html_files
for link in $url2; do
    curl -s -w '%{filename_effective}\n' -O "$link"
done

Without the -w formatstring option, the output of curl does not normally contain the output file name in a conveniently machine-readable format (or actually at all). I also added an -s option to disable the download status output it prints by default.

There is no point in doing cd to the same directory over and over again inside the loop, or capturing the output into a variable which you only use once to print to standard output the string which curl by itself would otherwise print to standard output.

Finally, the cd - does not seem to do anything useful here; even if it did something useful per se, you are doing it in a subshell, which doesn't change the current working directory of the script which contains the $(cd -) command substitution.

If your task is to temporarily switch to that directory, then switch back to where you started, just cd once. You can use cd - in Bash but a slightly more robust and portable solution is to run the fetch in a subshell.

( cd directory;
  do things ...
)
# you are now back to where you were before the cd

If you genuinely need the variable, you can trivially use

for link in $url2; do
    file1=$(curl -s -w '%{filename_effective}' -O "$link")
    echo "$file1"
done

but obviously the variable will only contain the result from the last iteration after the loop (in the code after done). (The format string doesn't need the final \n here because the command substitution will trim off any trailing newline anyway.)