Bash Validate User Input - linux

I'm making a small program that lets the user write their name and then proceeds to create a folder with the name they typed. I have this:
#!/bin/bash
echo "Enter your name:"
read name
mkdir /home/mint/Desktop/$name
That's working perfectly fine but I was wondering if there's a way to validate the input so that my program will only accept letters of the alphabet. Any help will be greatly appreciated.

There are many many ways to do this:
while true; do
read -p "Enter your name: " name
case "$name" in
*[^A-Za-z]*) echo "Only letters are allowed" ;;
*) break ;;
esac
done
mkdir ~/Desktop/"$name"
You'll want to find a tutorial. There's one here: http://mywiki.wooledge.org/EnglishFrontPage
Or start here on Stack Overflow: https://stackoverflow.com/tags/bash/info

You can do this:
#!/bin/bash
echo "Enter your name:"
read name
if [[ "$name" =~ ^[a-zA-Z]+$ ]]; then
echo "Creating directory: /home/mint/Desktop/$name"
mkdir /home/mint/Desktop/$name
else
echo "Your directory name may only use letters. Please try again."
fi
That's using a regular expression that allows only lowercase a-z and capital A-Z letters.

Something like this ?
#!/bin/bash
echo "Enter your name:"
read name
name=$(tr -dc [:alpha:] <<<"$name" )
mkdir "/home/mint/Desktop/$name"

Related

having an issue with my bash script

im writing a script that allows the user to create a backup of a file they choose by allowing them to input the file name. the file will then have backup followed by being date stamped at the end of it's name and saved on the home drive. but whenever i try to run it i get an error: cp: missing destination file operand after '_backup_2017_12_16'
here's my code:
title="my script 3"
prompt="Enter:"
options=("create a backup of a file")
echo "$title"
PS3="$prompt "
select opt in "${options[#]}" "Quit"; do
case "$REPLY" in
esac
cp "$filename""${file}_backup_$(date +%Y_%m_%d)"
done
Your case statement is currently empty. You need it to handle your chosen option
There needs to be a space between arguments: cp source dest
If you are using array for the options, you can also put Quit in there
If you choose the option to create a backup, you need to prompt the user to enter a filename. read command is used to get user input
Putting it all together, your script could look like this:
#!/usr/bin/env bash
options=("Backup" "Quit")
prompt="Enter: "
title="My script 3"
echo "$title"
PS3=$prompt
select opt in "${options[#]}"; do
case $opt in
"Backup")
IFS= read -r -p "Enter filename: " filename
cp -- "$filename" "${filename}_backup_$(date +%Y_%m_%d)" && echo "Backup created..."
;;
"Quit") break ;;
*) echo "Wrong option..." ;;
esac
done

Reading multiple files/folders with shellscript

I am using the read command to capture the files/folder names and further checking if they exist but below script only works with a single file/folder and does not work to capture multiple files/folders. Please help!
Thank you!
echo -n "Please enter a name of file/folder you wish to backup: "
read FILE
while [ ! -e "$FILE" ] ;do
read -p "The file ["$FILE"] does not exist."
echo -n "Please enter a name of file/folder you wish to backup: "
read FILE
done
I recommend taking an approach similar to this:
You can use CTRL + C to force an exit.
Please note that this should really be an if statement like to
ensure proper flow of logic as && || does not equate to if
then else logic
if [ "foo" = "foo" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fi
https://github.com/koalaman/shellcheck/wiki/SC2015

How to create a shell script that can scan a file for a specific word?

one of the questions that I have been given to do for my Computer Science GCSE was:
Write a shell script that takes a string input from a user, asks for a file name and reports whether that string is present in the file.
However way I try to do it, I cannot create a shell script.
I don't need you to tell me the whole number, however, I have no idea where to start. I input the variable and the file name, however, I have no idea how to search for the chosen word in the chosen file. Any ideas?
Using grep can get this working, for example
viewEntry()
{
echo "Entering view entry"
echo -n "Enter Name: "
read input
if grep -q "$input" datafile
then
echo ""
echo -n "Information -> "
grep -w "$input" datafile
echo ""
else
echo "/!\Name Not Found/!\\"
fi
echo "Exiting view entry"
echo ""
}
dataFile is the file you would be reading from. Then making use of -q and -w arguments of grep, you should be able to navigate your chosen file.
This site does a great job explaining grep and your exact problem: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/
The following shell-script is a very quick approach to do what you suggested:
#!/bin/sh # Tell your shell with what program this script should be exectued
echo "Please enter the filename: "
read filename # read user input into variable filename
count=`grep -c $1 $filename` # store result of grep into variable count
if [ $count -gt 0 ] # check if count is greater than 0
then
echo "String is present:" $1
else
echo "String not found:" $1
fi
You should look at some tutorials to get the basics of shell-scripting. Your task isn't very complex, so after some reading you should be able understand what the script does and modify it according your needs.

Smarter and more condensed method to match input variable in shell script?

I have a file with a list of numerous unique items, for this example I am using user ID's. The starting section of my script should display the list to the user running the script and allow them to chose one of the ID's. The script should then cross check the choice made by the user against the original file and if it matches it should provide a message advising of the match and continue with the script. If it does not match, the script should advise the user and exit.
My current script does this OK, but I was wondering if there is any way to make it a bit smarter/more condensed, perhaps using arrays? Current script:
This is my first post on this site so I apologies in advanced for any mistakes which have been made in the process of posting.
FILE=testfile
IDLIST="$(awk '{print $1}' $FILE)"
echo "$IDLIST"
echo "\nSelect one of the options"
read input
OUTPUT="$(for i in $IDLIST
do
if [[ $i = $input ]]
then
echo "Matched."
fi
done)"
if [[ -z $OUTPUT ]]
then
echo "Invalid choice."
exit 0
else
ID=$input
fi
echo "It is a match, continuing with script"
As you can imagine, there are many ways of doing this. One is using select instead:
PS3="Select an ID: "
select id in $(cut -d ' ' -f 1 testfile)
do
[[ -z $id ]] && echo "Pick a number" || break
done
echo "You selected $id"

Linux file deletion error

Every time I run this code I get the error File or directory doesn't exist. Why?
read -p "Enter the filename/path of the file you wish to delete : " filename
echo "Do you want to delete this file"
echo "Y/N"
read ans
case "$ans" in
Y) "`readlink -f $filename`" >>~/TAM/store & mv $filename ~/TAM/dustbin
echo "File moved" ;;
N) "File Not deleted" ;;
esac
When I enter the file name/directory exactly and triple check its right I still get this error, but the readlink part works.
Paraphrasing/summarizing/extending my answer for a similar question:
I doubt you really meant to use & instead of && in your script.
"File Not deleted" is not a valid command on any Linux system that I have used. Perhaps you are missing an echo there?
You have to fix your variable quotation. If the filename variable contains whitespace, then $filename is expanded by the shell into more than one arguments. You need to enclose it into double quotes:
mv "$filename" ~/TAM/dustbin
I do not see your script creating the ~/TAM/ directory anywhere...
You are missing an echo and one &&.
Use echo "`command`" to pipe the result string of commands. Alternatively, you may directly use the command without backticks and quotes, (not storing the result in a string), in which case you do not need an echo because the command will pipe its result to the next command.
The single & will run the preceding command in the background (async.). To check for return values and conditionally execute you need && and ||.
Here is a complete solution/example (incl. some more logging):
# modified example not messing the $HOME dir.
# should be save to run in a separate dir
touch testfile #create file for testing
read -p "Enter the filename/path of the file you wish to delete : " filename
echo "Do you want to delete this file: $filename"
echo "Y/N"
read ans
touch movedfiles #create a file to store the moved files
[ -d _trash ] || mkdir _trash #create a dustbin if not already there
case "$ans" in
Y) readlink -f "$filename" >> movedfiles && echo "File name stored" &&
mv "$filename" _trash && echo "File moved" ;;
N) echo "File Not deleted" ;;
esac
cat movedfiles #display all moved files

Resources