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