Shell script arguments - unix

I just started writing shell scripts in Unix so, I am a total newbie
I want to read the arguments given when the user run the script
ex:
sh script -a abc
I want to read for argument -a user gave abc.
My code so far:
if ( $1 = "-a" )
then var=$2
fi
echo $var
I get an error.

Bash uses an external program called test to perform boolean tests, but that program is used mostly via its alias [.
if ( $1 = "-a" )
should become
if [ $1 = "-a" ]
if you use [ or
if test $1 = "-a"

#!/bin/sh
if [ $1 = "-a" ]; then
var=$2
fi
echo $var
You shoud be careful of the space between if and [

Related

Running custom zsh function for tmux status bar not displaying output

I'm wrote a function called test_status that I am trying to incorporate in my tmux status bar. To give some background, my tests will output to a file called .guard_result with either success or failure and the test_status function reads from that file and echoes a 💚 if my tests are passing and a ❤️ if they are failing.
The good news is running test_status works just fine, I'm just having trouble getting it to work with tmux. What am I missing here?
# ~/.oh-my-zsh/custom/aliases.zsh
function test_status {
if [ ! -f "./.guard_result" ]; then
echo "?"
return 1
fi
result="$(cat ./.guard_result)"
if [[ $result == *"success"* ]]
then
echo "💚";
elif [[ $result == *"fail"* ]]
then
echo "❤️";
fi
}
This function works... Here is Tmux configuration (which doesn't show result):
# ~/.tmux.conf
set -g status-right "#(test_status) #[fg=colour245]%d %b %Y #[fg=white]:: #[fg=colour245]%l:%M %p"
I know I must be missing something simple... Thanks for your help!
tmux passes shell commands to /bin/sh not zsh. And even if tmux would use zsh, the function would not be available in that context as ~/.zshrc, which loads oh-my-zsh, is only read for interactive shells.
In order to get the the output of test_status into tmux, I would suggest to put the function into a zsh script and call that.
You can either source ~/.oh-my-zsh/custom/aliases.zsh from within the script and then call test_status:
#!/usr/bin/zsh
# ^ make sure this reflects the path to zsh (`type zsh`)
source ~/.oh-my-zsh/custom/aliases.zsh
test_status
Or you can just put the entire function into the script, so as to not clutter alias.zsh:
#!/usr/bin/zsh
function test_status {
if [ ! -f "./.guard_result" ]; then
echo "?"
return 1
fi
result="$(cat ./.guard_result)"
if [[ $result == *"success"* ]]
then
echo "💚";
elif [[ $result == *"fail"* ]]
then
echo "❤️";
fi
}
Safe the script somewhere (e.g. /path/to/test_status.zsh), make it executable (chmod a+x /path/to/test_status.zsh) and call it by path in the tmux configuration.

Unix — run one script when wc of the file not matched

I want to run the script with different parameters if the wc of the text file is matched or not matched!
My Script:
#!/bin/sh
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
then
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com
elif
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com, hi.name#hi.com
fi
You need to capture the output of wc accurately, and you need to avoid getting a file name in its output. You have:
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
The space after the = is wrong. The echo is not wanted. You should use input redirection with wc. (wc is a little peculiar. If you give it a file name to process, it includes the file name in the output; if you have it process standard input, it doesn't include a file name in the output.) You should use $(…) in preference to back-quotes.
x=$(wc -l < "/scc/ftp/mrdr_rpt/yet_to_load.txt")
if [ $x -gt 0 ]
If you want to check if the file is not empty (rather than being a file with data but no newlines), then you can use a more direct test:
if [ -s "/scc/ftp/mrdr_rpt/yet_to_load.txt" ]
You should probably be using a name such as
DIR="/scc/ftp/mrdr_rpt"
and then referencing it to reduce the ugly repetitions in your code:
if [ $x -gt 0 ]
then
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com
else
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com, hi.name#hi.com
fi
However, I think the comma in the second line is probably not needed, and it might be better to use:
who="from#from.com to.name#to.com"
if [ -s "$DIR/yet_to_load.txt" ]
then who="$who hi.name#hi.com"
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" $who
Then you've only one line with all the names in it. And you might do even better with an array instead of string:
who=("from#from.com" "to.name#to.com")
if [ -s "$DIR/yet_to_load.txt" ]
then who+=("$who hi.name#hi.com" "Firstname Lastname <someone#example.com>")
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" "${who[#]}"
Using arrays means you can handle blanks in the names correctly where a simple string doesn't.

Location=$1? what does it mean?

#!/bin/bash
LOCATION=$1
FILECOUNT=0
DIRCOUNT=0
if [ "$#" -lt "1" ]
then
echo "Usage: ./test2.sh <directory>"
exit 0
fi
I don't actually get what the If statement is saying can anyone help me to explain this?Thank you
$1 refers to the first argument of the bash file. In this case, you can pass your directory path by issuing the following command:
# ./test2.sh /path/of/your/directory
#!/bin/bash
LOCATION=$1 #first argument of the script
FILECOUNT=0
DIRCOUNT=0
if [ "$#" -lt "1" ] #if the number of argument(s) ($#) is less than 1
then
echo "Usage: ./test2.sh <directory>"
exit 0
fi
You can read this article for more information about parameter passing.
Hope it helps.
$1 is the first argument that is passed to the bash script. If you start the script like ./test2.sh argument1 argument2 the $1 will refer argument1.
The if-statement checks, if the count of arguments (that's the $#) is smaller than 1, then it will output the usage statement (as it seems you can't run the script without any argument).

UNIX valid_password

why in Cygwin Terminal - the if statement work
and ubuntu - unix - not working for
this code :
#!/bin/sh
valid_password="pass"
echo "Please enter the password:"
read password
if [ "$password" == "$valid_password" ]
then
echo "You have access!"
else
echo "Access denied!"
fi
#emil pointed the answer:
if [ "$password" = "$valid_password" ]
instead of
if [ "$password" == "$valid_password" ]
Also: did you give the script executing permissions? Try
chmod +x script_name
because the correct syntax to [ is:
[ a = b ]
From your error message it sounds like you wrote:
if ["$password" = "$valid_password" ]
change this to:
if [ "$password" = "$valid_password" ]
notice the space after [. if just takes a shell command, try to run it and depending if the exit code from the program is 0 it will run the commands inside the if statement.
In your terminal, write i.e.:
user#localhost$ true; echo $?
0
to test your if statement:
user#localhost$ pass=pass; valid=pass
user#localhost$ if [ "$pass" = "$valid" ]; then echo 'You have access!'; fi
As #nullrevolution said, the ! is evaluated if you use double quotes, it will try to run last command in your shell history, in this case that is matching u.
user#localhost$ uname
Linux
user#localhost$ !u
uname
Linux
user#localhost$ echo "!"
sh: !: event not found
This is because the ! is evaluated before the double quotes are matched, and echo is run. If you still want to use double quotes, you will have to escape the ! outside the quotes:
echo "Access denied"\!
#nullrevolution also said you could try with bash, which has a builtin syntax for the expression inside if statements.
#!/bin/bash
valid_password=pass
echo "Please enter the password:"
read password
if [[ "$password" == "$valid_password" ]]; then
echo 'You have access!'
else
echo 'Access denied!'
fi
Also in your program I guess you do not want to echo the password in the terminal, to turn off echo temporary change:
read password
to
stty -echo
read password
stty echo
if you forgot to write stty echo to turn on echo again, just write reset in your terminal, and it will reset the terminal to default settings.
A useful tutorial for bourn shell script can be found here:
http://www.grymoire.com/Unix/Sh.html

How to custom display prompt in KornShell to show hostname and current directory?

I am using KornShell (ksh) on Solaris and currently my PS1 env var is:
PS1="${HOSTNAME}:\${PWD} \$ "
And the prompt displays: hostname:/full/path/to/current/directory $
However, I would like it to display: hostname:directory $
In other words, how can I display just the hostname and the name of the current directory, i.e. tmp or ~ or public_html etc etc?
From reading the ksh man page you want
PS1="${HOSTNAME}:\${PWD##*/} \$ "
Tested on default ksh on SunOS 5.8
Okay, a little old and a little late, but this is what I use in Kornshell:
PS1='$(print -n "`logname`#`hostname`:";if [[ "${PWD#$HOME}" != "$PWD" ]] then; print -n "~${PWD#$HOME}"; else; print -n "$PWD";fi;print "\n$ ")'
This makes a prompt that's equivalent to PS1="\u#\h:\w\n$ " in BASH.
For example:
qazwart#mybook:~
$ cd bin
qazwart#mybook:~/bin
$ cd /usr/local/bin
qazwart#mybook:/usr/local/bin
$
I like a two line prompt because I sometimes have very long directory names, and they can take up a lot of the command line. If you want a one line prompt, just leave off the "\n" on the last print statement:
PS1='$(print -n "`logname`#`hostname`:";if [[ "${PWD#$HOME}" != "$PWD" ]] then; print -n "~${PWD#$HOME}"; else; print -n "$PWD";fi;print "$ ")'
That's equivalent to PS1="\u#\h:\w$ " in BASH:
qazwart#mybook:~$ cd bin
qazwart#mybook:~/bin$ cd /usr/local/bin
qazwart#mybook:/usr/local/bin$
It's not quite as easy as setting up a BASH prompt, but you get the idea. Simply write a script for PS1 and Kornshell will execute it.
For Solaris and other Older Versions of Kornshell
I found that the above does not work on Solaris. Instead, you'll have to do it the real hackish way...
In your .profile, make sure that ENV="$HOME/.kshrc"; export ENV
is set. This is probably setup correctly for you.
In your .kshrc file, you'll be doing two things
You'll be defining a function called _cd. This function will change to the directory specified, and then set your PS1 variable based upon your pwd.
You'll be setting up an alias cd to run the _cd function.
This is the relevant part of the .kshrc file:
function _cd {
logname=$(logname) #Or however you can set the login name
machine=$(hostname) #Or however you set your host name
$directory = $1
$pattern = $2 #For "cd foo bar"
#
# First cd to the directory
# We can use "\cd" to evoke the non-alias original version of the cd command
#
if [ "$pattern" ]
then
\cd "$directory" "$pattern"
elif [ "$directory" ]
then
\cd "$directory"
else
\cd
fi
#
# Now that we're in the directory, let's set our prompt
#
$directory=$PWD
shortname=${directory#$HOME} #Possible Subdir of $HOME
if [ "$shortName" = "" ] #This is the HOME directory
then
prompt="~$logname" # Or maybe just "~". Your choice
elif [ "$shortName" = "$directory" ] #Not a subdir of $HOME
then
prompt="$directory"
else
prompt="~$shortName"
fi
PS1="$logname#$hostname:$prompt$ " #You put it together the way you like
}
alias cd="_cd"
This will set your prompt as the equivelent BASH PS1="\u#\h:\w$ ". It isn't pretty, but it works.
ENV=~/.kshrc, and then in your .kshrc:
function _cd {
\cd "$#"
PS1=$(
print -n "$LOGNAME#$HOSTNAME:"
if [[ "${PWD#$HOME}" != "$PWD" ]]; then
print -n "~${PWD#$HOME}"
else
print -n "$PWD"
fi
print "$ "
)
}
alias cd=_cd
cd "$PWD"
Brad
HOST=`hostname`
PS1='$(print -n "[${USER}#${HOST%%.*} ";[[ "$HOME" == "$PWD" ]] && print -n "~" ||([[ "${PWD##*/}" == "" ]] && print -n "/" || print -n "${PWD##*/}");print "]$")'
PS1=`id -un`#`hostname -s`:'$PWD'$
and...
if you work between two shells for most of your effort [ksh and bourne sh]
and desire a directory tracking display on your command line
then PWD can be substituted easily in ksh
and if you use /usr/xpg4/bin/sh for your sh SHELL, it will work there as well
Try this:
PS1="\H:\W"
More information on: How to: Change / Setup bash custom prompt, I know you said ksh, but I am pretty sure it will work.

Resources