I wanna write a script which check variables of this script.
I have tried some, but it isn't working. The idea is:
If on of the parameters is a number, print that it is number
If on of the parameters is a character, print that it is character
If 'man parameter' is executable, print that it is might be a function
Script I have tried:
#!/bin/bash
echo Hello $LOGNAME'!'
test $# -eq 0 && echo 'Try again, no parameters were entered' || echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in $*
do
if ![["$i" =~ $re]];then
echo 'Parameter '$i' is alphabetical'
else
if [["$i" =~ $re]];then
echo 'Parameter '$i' is digital'
else
if [ $i];then
echo $i' might be a function. Try to use man of --help'
fi
fi
fi
done
#!/bin/bash
echo "Hello ${LOGNAME}!"
[ "$#" -eq 0 ] && { echo 'Try again, no parameters were entered'; exit 1; }
echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in "$#"
do
if ! [[ "$i" =~ $re ]];then
echo "Parameter '$i' is alphabetical"
man "$i" > /dev/null 2> /dev/null
if [ "$?" -eq 0 ];then
echo "$i might be a function. Try to use man of --help"
fi
else
echo "Parameter '$i' is digital"
fi
done;
When you write a test you need spaces around your brackets.
You can easily find and fix those bugs if you use shellcheck
Related
I would like to put below check in a for loop but do not know how to put the variables as input list, just like $A,$B,$C
A="file name1.txt"
B="file name2.txt"
C="file name3.txt"
if [[ ! -f "$A" ]]; then
echo "file $A not exist"
fi
if [[ ! -f "$B" ]]; then
echo "file $B not exist"
fi
if [[ ! -f "$C" ]]; then
echo "file $C not exist"
fi
#!/bin/bash
A="file name1.txt"
B="file name2.txt"
C="file name3.txt"
for file in "$A" "$B" "$C"; do
if [[ ! -f "$file" ]]; then
echo "file $file not exist"
fi
done
The use of [[ is not POSIX and supported only on ksh, zsh, and bash. It does not require a fork() and is, in general, safer. You can substitute [ and ] respectively for a POSIX compliant script.
you can use the following commands:
#!/bin/bash
FILES_TO_CHECK_ARRAY=( "file name1.txt" "file name2.txt" "file name3.txt" )
for current_file in "${FILES_TO_CHECK_ARRAY[#]}"
do
if [[ ! -f "${current_file}" ]]; then
echo "file ${current_file} not exist"
fi
done
When I run the below code with exact two arguments, the else block doesn't get executed.
If I take out the if else block out of the function, everything works fine.
#!/bin/bash
usage() {
if [[ $# -gt 2 || $# -lt 2 ]]; then
echo "insufficient args"
else
if [[ $# -eq 2 ]]; then
echo "continuing with the script"
fi
fi
}
usage
In this situation, the function usage is receiving 0 arguments from the call.
Change the call to usage $#, which will pass the command line arguments to the usage function.
#!/bin/bash
usage() {
if [[ $# -gt 2 || $# -lt 2 ]]; then
echo "insufficient args"
else
if [[ $# -eq 2 ]]; then
echo "continuing with the script"
fi
fi
}
usage "$#"
for var in "$#"
do
if test -z $var
then
echo "missing operand"
elif [ -d $var ]
then
echo "This is a directory"
elif [ ! -f $var ]
then
echo "The file does not exist"
else
basename=$(basename $var)
dirname=$(readlink -f $var)
inodeno=$(ls -i $var| cut -d" " -f1)
read -p "remove regular file $#" input
if [ $input = "n" ]
then exit 1
fi
mv $var "$var"_"$inodeno"
echo "$basename"_"$inodeno":"$dirname" >> $HOME/.restore.info
mv "$var"_"$inodeno" $HOME/deleted
fi
done
**Hello, the above code is trying to mimic the rm command in unix. Its purpose is to remove the file .
Eg if I type in bash safe_rm file1 , it works however if type in
bash safe_rm file1 file 2 , it prompts me to remove file 1 twice and gives me a unary operater expected for line 27(if [ $input = "n" ]).
Why does it not work for two files, ideally I would like it to prompt me to remove file1 and file 2.
Thanks
read -p "remove regular file $#" input
should probably be
read -p "remove regular file $var" input
That's the basic.
And this is how I'd prefer to do it:
for T in "$#"; do
if [[ -z $T ]]; then
echo "Target is null."
elif [[ ! -e $T ]]; then
echo "Target does not exist: $T"
elif [[ -d $T ]]; then
echo "Target can't be a directory: $T"
else
BASE=${T##*/}
DIRNAME=$(exec dirname "$T") ## Could be simpler but not sure how you want to use it.
INODE_NUM=$(exec stat -c '%i' "$T")
read -p "Remove regular file $T? "
if [[ $REPLY == [yY] ]]; then
# Just copied. Not sure about its logic.
mv "$T" "${T}_${INODE_NUM}"
echo "${BASE}_${INODE_NUM}:${DIRNAME}" >> "$HOME/.restore.info"
mv "${T}_${INODE_NUM}" "$HOME/deleted"
fi
fi
done
Long story short, I need to write a shell script. The script will take a single command line argument which will be a directory path.
The script will then read each of the files in that directory and output it to standard output; the output will be in HTML and will be a table.
The files will be in this format:
owner sysadmin group
admin ajr
loc S-309
ser 18r97
comment noisy fan
What I have so far:
PATH=/bin:/usr/bin
cd "$#"
if [ test $? -ne 0]
then
exit 1
fi
filenames=$(ls "$#")
for i in $filenames
do
while read item value
do
if [ $item="owner" ] || [ $item="admin" ] || [ $item="loc" ] || [ $item="ser"]
then
a[$item]=$value
fi
done < i
done
echo '<html>'
echo '<body>'
echo '<table border=1>'
echo '<tr><th>hostname</th><th>location</th><th>Admin</th><th>Serial Number</th><th>owner</th><tr>'
for i in filename
do
echo '<tr><td>'$i'</td><td>'${i[loc]}'</td><td>${i[admin]}'</td><td>'${i[ser]}'</td><td>'${i[owner]}'</td><tr>'
done
echo
echo '</table>'
echo '</body>'
echo '</html>'
The HTML isn't my main concern since I am just following a format given, with each of the values going in between. However, I am getting an error that I have no idea why:
invrep: line 10: i: no such file or directory
but I am using it in a loop. Why is it giving me this error?
Also to confirm, the directory that I used exists; I'm not sure if that has to do with anything though.
Caveat Lector: the code in the question has been edited. The code I commented on may not be the code you can see.
Not directly the problem (chepner diagnosed that in his comment), but:
cd "$#"
if [ test $? -ne 0]
then
exit 1
fi
has a variety of problems. You don't verify that there's only one argument, and you pass all the arguments that are given to cd, which may just quietly ignore the surplus. The test line should use either [ or test but not both. If you use [, the last argument must be ] so you're missing a space:
if test $? -ne 0
if [ $? -ne 0 ]
However, you could short circuit that paragraph by:
cd "$#" || exit 1
(or you could drop the 1 even, though I'd leave it there).
You might want to consider:
case $# in
1) cd "$1" || exit 1;;
*) echo "Usage: $0 directory" >&2; exit 1;;
esac
This verifies that a single argument was passed and that it names a directory you can cd to.
Your looping code also has problems. The while loop should be redirected from "$i" once you've fixed things up:
filenames=$(ls "$#")
for i in $filenames
do
while read item value
do
if [ $item="owner" ] || [ $item="admin" ] || [ $item="loc" ] || [ $item="ser"]
then
a[$item]=$value
fi
done < $i
# Print HTML here!! Not after this loop
done
Your HTML loop has a lot of problems too — notably using $i as an array instead of $a.
PATH=/bin:/usr/bin
case $# in
1) cd "$1" || exit 1;;
*) echo "Usage: $0 directory" >&2; exit 1;;
esac
echo '<html>'
echo '<body>'
echo '<table border=1>'
echo '<tr><th>hostname</th><th>location</th><th>Admin</th><th>Serial Number</th><th>owner</th><tr>'
filenames=$(ls "$#")
for i in $filenames
do
while read item value
do
if [ $item="owner" ] || [ $item="admin" ] || [ $item="loc" ] || [ $item="ser"]
then
a[$item]=$value
fi
done < $i
echo "<tr><td>$i</td><td>${a[loc]}</td><td>${a[admin]}</td><td>${a[ser]}</td><td>${a[owner]}</td><tr>"
done
echo '</table>'
echo '</body>'
echo '</html>'
And that still doesn't fix the problem with using ls to generate a list of file names. For that, given the rest of the script, lose filenames altogether and use for file in * instead. You then need to quote $i in the I/O redirection, too.
PATH=/bin:/usr/bin
case $# in
1) cd "$1" || exit 1;;
*) echo "Usage: $0 directory" >&2; exit 1;;
esac
echo '<html>'
echo '<body>'
echo '<table border=1>'
echo '<tr><th>hostname</th><th>location</th><th>Admin</th><th>Serial Number</th><th>owner</th><tr>'
for i in *
do
while read item value
do
if [ $item = "owner" ] || [ $item = "admin" ] ||
[ $item = "loc" ] || [ $item="ser"]
then
a[$item]=$value
fi
done < "$i"
echo "<tr><td>$i</td><td>${a[loc]}</td><td>${a[admin]}</td><td>${a[ser]}</td><td>${a[owner]}</td><tr>"
done
echo '</table>'
echo '</body>'
echo '</html>'
(Also fixed spacing in the if statement in the loops. The code is still not very elegant, but it is somewhat related to the original code.)
filenames=$(ls "$#")
is wrong, and should never be used by anyone. See the first entry in http://mywiki.wooledge.org/BashPitfalls, or the entire page http://mywiki.wooledge.org/ParsingLs.
If your argument list is a set of directories, the inner loop would look more like this:
declare -A a
for dir in "$#"; do
for i in "$dir/"*; do
while read -r item value; do
case $item in
owner|admin|loc|ser)
a[$item]=$value
;;
esac
done <"$i"
done
done
I have a shell script variable
$a = "Hello i am pass"
now i want to search for "pass" in variable $a.
if ["$a" == "pass"]; then
echo "`Success`"
else
echo "`fail`"
fi
Please give me shell script for searching pass keyword to use in above code.
Try with this,
#!/bin/bash
a="Hello i am pass";
if [ `echo $a | grep -c "pass" ` -gt 0 ]
then
echo "Success"
else
echo "Fail";
fi
flag=`echo $a|awk '{print match($0,"pass")}'`;
if [ $flag -gt 0 ];then
echo "Success";
else
echo "fail";
fi
Here is a more compact way to write this:
echo "$a" | grep "pass" && echo "Found." || echo "Not found."
You can use braces to put in multiple instructions instead of a simple echo:
echo "$a" | grep "pass" && {echo "Found.";exit 0} || {echo "Not found.";exit 1}
today i used extended choice parameter and using execute shell for the string match.
if someone will find same problem anyone can use this
if [ `echo $test| grep -c "abc" ` -gt 0 ]
then
echo "Success"
else
echo "Fail";
fi
Try this
a="Hello I am Pass";
a1="Hello, Passed my First Attempt"
a2="Passed in First Attempt"
if [[ ${a,,} =~ 'pass' ]]; then echo 'Success'; else echo 'First Attempt in Learning'; fi
Short command:
OPC="test"
PROD="This is a test"
[[ ${PROD,,} =~ $OPC ]] && echo -n 1 || echo -n 0
The answer will be "1" when find "OPC" in "PROD".