Home > Enterprise >  Make Bash script accept either a filename or a line of text entered in the command line
Make Bash script accept either a filename or a line of text entered in the command line

Time:09-27

I'm working on a very basic ROT-5 (text only) converter, as a way of learning Bash and dabbling in cryptography and logic.

I've got it to work by taking the contents of a file and shifting the letters forward 5 places, as follows:

#!/bin/bash

echo $(<$1) 

echo $(<$1) | tr 'A-Za-z' 'F-ZA-Ef-za-e'

so for example if I enter the following command:

#./rot5.sh filename.txt

it will convert it fine. Is there any way to make it work so that if I was to enter the following:

./rot5.sh encodemysecretmessage

It would apply the tr to the encodemysecretmessage instead of looking for a filename?

CodePudding user response:

I'd recommend being explicit and using a command-line flag, for example, -s:

$ ./rot5.sh test.txt
foobar
kttgfw

$ ./rot5.sh -s "my secret message"
my secret message
rd xjhwjy rjxxflj

Here's an example implementation:

case $1 in
-s)
    # Handle data as a string.
    printf '%s\n' "$2"
    ;;
*)
    # Otherwise, handle data as a filename.
    cat -- "$1"
    ;;
esac | tee >(tr 'A-Za-z' 'F-ZA-Ef-za-e')

(How the last line works is tee takes its input and prints it as well as forwarding it to a file. Here I'm replacing the file with a process substitution.)


Note: This is just a barebones demo. For anything more complicated than this, handling command-line flags well is actually really difficult, so instead I'd probably use getopts, which requires a bit of boilerplate. Here's a tutorial from a good source, though I haven't read it myself.

CodePudding user response:

Here's the working solution with the help from @Robert: Lots of thanks for that :)

#!/bin/bash

if [ -f "$1" ]; then
        echo $(<$1) 
        echo $(<$1) | tr 'A-Za-z' 'F-ZA-Ef-za-e'
else
        echo "$1"
        echo "$1" | tr 'A-Za-z' 'F-ZA-Ef-za-e'  
fi
  •  Tags:  
  • bash
  • Related