-1

So this is short script used to rename extension of files i found on tldp.

#!/bin/bash
Mysterious=65
case $# in
 0|1)
 echo "Usage: `basename $0` old_file_extension new_file_extension"
 exit $Mysterious
 ;;
esac

for filename in *.$1
do
 mv $filename ${filename%$1}$2
done
exit 0

I don't understand about the value of Mysterious variable. Why did the script's owner choose 65 and why we had to use case $# in 0 or 1? I changed value 65 into 100 and it still worked.

The One
  • 4,862
  • It's the exit code, and you'd have to ask the author why they chose that number... – jasonwryan May 16 '16 at 03:03
  • Sorry, the script was posted on the tlpd for a long time and no one even knows who is the author of that script. Do you have any idea about meaning of that variable? – The One May 16 '16 at 03:06
  • 0|1) just means the script has to be passed more than 1 argument... – jasonwryan May 16 '16 at 03:22
  • 3
    I wouldn't use that script for anything except an example of how not to write a shell script. It's terrible. For starters, none of the variables are properly quoted, and it seems to require exactly two args, but is written so that 2 or more args will be accepted - this is a bug. The final exit 0 is superfluous, that's the default when a script ends normally. – cas May 16 '16 at 03:53
  • Thanks for your answer. When i was searching for some tutorials about bash script, i found one page contained this script. Maybe that's not a good resource. Do you know where i could find bash script snippet to practice? – The One May 16 '16 at 09:12

1 Answers1

2

The person who wrote that script apparently wrongly thought that the exit status could represent a security issue. If they had named it parmError or something like that it would have made more sense.

Here's a better way to do this that also supports spaces and special chars:

#!/bin/bash

if test "$#" -ne 2
then
        echo "Usage: $0 old_file_extension new_file_extension"
        exit 2
fi

for filename in *."$1"
do
        mv "$filename" "${filename%$1}$2"
done

Note that there's no need to return 0 as it's the default.

Wildcard
  • 36,499
  • 1
    Filenames can contain tabs and newlines. Just quote the variables, always. And you don't to parse an ls command ever, just use shell globbing. – Wildcard May 16 '16 at 05:01
  • 1
    I had initially tried it and done a mistake so I tested it again to follow your advice and this looks good. – Julie Pelletier May 16 '16 at 05:13
  • 1
    Almost; I fixed the remaining instances. Even when you want globbing on a string that will include parameter expansion, you can put the parameter expansion itself in quotes. – Wildcard May 16 '16 at 05:38
  • 1
    Right, I forgot it when I removed the ls. – Julie Pelletier May 16 '16 at 05:46
  • 1
    Since the script isn't using any Bashisms, it would be nice for the shebang to read #!/bin/sh which also helps to make it more portable. Also, the exit status has no more meaning for than in the original script, the OP could have come across it and thought “Why is there a 2 there? What does it mean?” Although it's a small script, would it be better to define a descriptive variable name with the value '2' and use that as an exit status? It also helps should such a script grow and uses the exit status in multiple places or has multiple exit statuses to manage. – forquare May 16 '16 at 06:21