@b0rk_reruns do NOT do loops like this! this is DANGEROUS
1. iterating over a list of files is fine. and if you know that your filenames don’t contain spaces, your approach will work. otherwise, you will iterate over a part of the filename, not the full one. Best case, your script doesn’t do anything. worst case, it spews garbage in your $PWD and you need to manually clean it up
correct way to do it:
IFS=$'\n'
for i in *.png; do
convert -- "$i" "${i/.png/.jpg}"
done
IFS (inner-field separator) is a special variable which tells bash when to split stuff. By default, it’s a space; We set it to newline, because it’s a safe assumption that a file won’t have one.
1. try to prefix your file parameters with a double dash (--
). this is a somewhat-standard way of terminating named arguments and specifying that everything after this point is raw data.
Terminating arguments is important if you use a variables that you don’t necessarily control. Take this for example:
a="-nastyFilename.jpg"
convert "$a" output.png
This will fail, because imagick will try to interpret the first arg as a switch. This can wreck havoc on your system, don’t ask how i know.
1.
always quote your variables, unless you truly want them to expand! if you don’t, they may get passed as separate args to a command you’re executing.
2.
if your directory is HUGE (over 30k files), don’t use for
; this is because for every command there’s an argument amount limit, and *
expands to one arg per file. instead, do this:
while read i; do
echo "$i"
done <<< $(ls)
another, even better way is to use find
with its -exec option:
find . -maxdepth 1 -exec echo {} \;
anyways, sorry for the rant. i know a little bit too much bash, and i wish this curse upon everyone else >:3