I am trying to write a simple bash script on Ubuntu 12.10 which stores the result of the pwd command in a variable and then checks the value of that variable in an if command to see if it matches a particular string. But I keep getting an error because it treats the content of that variable as a directory itself and keeps giving the error "No such file or directory"
The program is as below:
myvar=$(pwd)
if [$myvar -eq /home/vicky] #fails this check as variable myvar contains /home/vicky
then
echo correct
else
echo incorrect
fi
Any help would be appreciated
The proper form for that is
myvar=$(pwd)
if [ "$myvar" = /home/vicky ] ## Need spaces and use `=`.
And since you're in bash, you don't need to use pwd. Just use $PWD. And also, it's preferrable to use [[ ]] since variables are not just to word splitting and pathname expansion when in it.
myvar=$PWD
if [[ $myvar == /home/vicky ]]
Or simply
if [[ $PWD == /home/vicky ]]
Related
Hi I have written small shell script, I am not able to understand the behavior of that script. can any one help me to understand that script.
Script:
#!/bin/bash
if [ -z $1 ]
then
echo "fail"
else
echo "success"
fi
While executing the script .
./test.sh one
It exuting the else statement instead of main statement , even though its passing the argument.
can any one explain me this behavior to understand
The -z test in bash is checking if a string is an empty (zero length) value.
Since you're passing an argument to the script $1 is not empty and therefore -z $1 evaluates to false, executing the else portion of your script.
Side note: Since you're working with strings I recommend you to quote variables as follows:
if [ -z "$1" ]; then
echo "String is empty / No argument given"
else
echo "String is not empty / Argument given"
fi
Edit:
As pointed out by user1934428 it's probably better to use [[ instead of [. This, among others, eliminates the need for quoting. See more differences here.
if [[ -z $1 ]]; then
...
However, be aware that this is a bash extension and won't work in sh scripts.
bash
Hi! I have to make a bash script that takes a directory as an option.
If other options are given, the output should only be "Error".
Let's c be the value given to the only argument if no argument is given,
then c =. (Point)!
But i don't know how i can make this.
Can you help me, thanks a lot.
So you need to provide an argument to a bash function which needs to be a directory. If it is not a directory then the program should display "Error". If no argument is supplied, the directory should be "." (current directory?)
#!/bin/bash
if [[ ! -z $1 ]]; then
c=$1
if [[ ! -d $c]]; then
echo "Error"
fi
else
c="."
fi
In my shell script i'm trying to check if a specific file is exists and if it has reading permissions.
My file's path has spaces in it.
I quoted the file path:
file='/my/path/with\ some\ \spaces/file.txt'
This is the function to check if the file exists:
#Check if file exists and is readable
checkIfFileExists() {
#Check if file exists
if ! [ -e $1 ]; then
error "$1 does not exists";
fi
#Check if file permissions allow reading
if ! [ -r $1 ]; then
error "$1 does not allow reading, please set the file permissions";
fi
}
Here I double quote to make sure it gets the file as a one argument:
checkIfFileExists "'$file'";
And I receive an error from the bash saying:
[: too many arguments
Which make me thinks it doesn't get it as a one argument.
But in my custom error, I do get the whole path, and it says it doesn't exists.
Error: '/my/path/with\ some\ \spaces/file.txt' does not exists
Although it does exists, and when I tried to read it with "cat $file" I get a permission error..
what am I'm doing wrong?
The proper way to quote when you require variable interpolation is with double quotes:
if [ -e "$1" ]; then
You need similar quoting throughout the script, and the caller needs to quote or escape the string -- but not both. When you assign it, use one of these:
file='/my/path/with some spaces/file.txt'
# or
file=/my/path/with\ some\ spaces/file.txt
# or
file="/my/path/with some spaces/file.txt"
then use double quotes around the value to pass it in as a single argument:
checkIfFileExists "$file"
Again, where you need the variable's value to be interpolated, use double quotes.
For a quick illustration of what these quotes do, try this:
vnix$ printf '<<%s>>\n' "foo bar" "'baz quux'" '"ick poo"' \"ick poo\" ick\ poo
<<foo bar>>
<<'baz quux'>>
<<"ick poo">>
<<"ick>>
<<poo">>
<<ick poo>>
Furthermore, see also When to wrap quotes around a shell variable?
if [[ -e $1 ]];then
echo it exists
else
echo it doesnt
fi
if [[ -r $1 ]];then
echo readable
else
echo not readable
fi
First of all, hi to everyone, that's my first post here.
I swear I have checked the site for similar questions to avoid the "double post about same argument" issue but none of them answered exactly to my question.
The problem is that in the code below I always get the "There are no files with this extension" message when I call the script passing it an extension as first argument.
#!/bin/bash
if [ "$1" ];
then
file=*."$1";
if [ -f "$file" ];
then
for i in "$file";
[...do something with the each file using "$i" like echo "$i"]
else
echo "There are no files with this extension";
fi;
else
echo "You have to pass an extension"
fi;
I tried using the double parenthesis, using and not using the quotes in the nested if, using *."$1" directly in the if, but none of this solution worked.
One problem is that you're not quoting a variable when you first assign a value to file. In this statement:
file=*."$1";
The * will be interpreted by the shell, so for example if you passed in .py on the command line, file might end up with the value file1.py file2.py, which will throw off your file existence test later on.
Another problem, as #sideshowbarker points out, is that you can't use wildcards with the [ -f ... ].
Another variable quoting issue is that quoting inhibits wildcard expansion, such that even without the file existence test, if $file is, e.g., *.txt, then this:
for x in "$file"; do ...
Will loop over a single argument with the literal value *.txt, while this:
for x in $file; do ...
Will loop over all files that end with a .txt extension (unless there are none, in which case it will loop once with $x set to the literal value *.txt).
Typically, you would write your script to expect a list of arguments, and allow the user to call it like myscript *.txt...that is, leave wildcard handling to the interactive shell, and just let your script process a list of arguments. Then it becomes simply:
for i in "$#"; do
echo do something with this file named "$x"
done
If you really want to handle the wildcard expansion in your script, something like this might work:
#!/bin/bash
if [ "$1" ];
then
ext="$1"
for file in *.$ext; do
[ -f "$file" ] || continue
echo $file
done
else
echo "You have to pass an extension"
fi;
The statement [ -f "$file" ] || continue is necessary there because of the case I mentioned earlier: if there are no files, the loop will still execute once with the literal expansion of *.$ext.
the following script is working fine on one server but on the other it gives an error
#!/bin/bash
processLine(){
line="$#" # get the complete first line which is the complete script path
name_of_file=$(basename "$line" ".php") # seperate from the path the name of file excluding extension
ps aux | grep -v grep | grep -q "$line" || ( nohup php -f "$line" > /var/log/iphorex/$name_of_file.log & )
}
FILE=""
if [ "$1" == "" ]; then
FILE="/var/www/iphorex/live/infi_script.txt"
else
FILE="$1"
# make sure file exist and readable
if [ ! -f $FILE ]; then
echo "$FILE : does not exists. Script will terminate now."
exit 1
elif [ ! -r $FILE ]; then
echo "$FILE: can not be read. Script will terminate now."
exit 2
fi
fi
# read $FILE using the file descriptors
# $ifs is a shell variable. Varies from version to version. known as internal file seperator.
# Set loop separator to end of line
BACKUPIFS=$IFS
#use a temp. variable such that $ifs can be restored later.
IFS=$(echo -en "\n")
exec 3<&0
exec 0<"$FILE"
while read -r line
do
# use $line variable to process line in processLine() function
processLine $line
done
exec 0<&3
# restore $IFS which was used to determine what the field separators are
IFS=$BAKCUPIFS
exit 0
i am just trying to read a file containing path of various scripts and then checking whether those scripts are already running and if not running them. The file /var/www/iphorex/live/infi_script.txt is definitely present. I get the following error on my amazon server-
[: 24: unexpected operator
infinity.sh: 32: cannot open : No such file
Thanks for your helps in advance.
You should just initialize file with
FILE=${1:-/var/www/iphorex/live/infi_script.txt}
and then skip the existence check. If the file
does not exist or is not readable, the exec 0< will
fail with a reasonable error message (there's no point
in you trying to guess what the error message will be,
just let the shell report the error.)
I think the problem is that the shell on the failing server
does not like "==" in the equality test. (Many implementations
of test only accept one '=', but I thought even older bash
had a builtin that accepted two '==' so I might be way off base.)
I would simply eliminate your lines from FILE="" down to
the end of the existence check and replace them with the
assignment above, letting the shell's standard default
mechanism work for you.
Note that if you do eliminate the existence check, you'll want
to either add
set -e
near the top of the script, or add a check on the exec:
exec 0<"$FILE" || exit 1
so that the script does not continue if the file is not usable.
For bash (and ksh and others), you want [[ "$x" == "$y" ]] with double brackets. That uses the built-in expression handling. A single bracket calls out to the test executable which is probably barfing on the ==.
Also, you can use [[ -z "$x" ]] to test for zero-length strings, instead of comparing to the empty string. See "CONDITIONAL EXPRESSIONS" in your bash manual.