I know how to check for a file in bash using this code
file=$1
if [ -f "$file" ]
then
...
fi
But I want to do something when it's not a file.
file=$3
if [ "$1" == "" ] || [ "$2" == "" ] || [ $file is not a file??? ]
then
echo "use: notEmpty notEmpty file"
fi
Can anyone help me out?
if [ "$1" == "" ] || [ "$2" == "" ] || [ ! -f "$file" ]
The whitespaces after [ and before ] are important.
Related
I want to list project directory all xcworkspace and xcodeproj file.
And I write code below
#!/bin/bash
workspaceFile="xcworkspace"
projectFile="xcodeproj"
#listFiles
path=$(pwd)
fileList=()
walk_dir () {
for name in "$path"/*; do
if [[ -d "$name" && ("${name##*.}" != ${projectFile} || "${name##*.}" != ${workspaceFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
done
}
walk_dir
for name in ${fileList[#]}; do
echo $name
done
It did not work.
But If change the condition, like below
if [[ -d "$name" && ("${name##*.}" != ${workspaceFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
or
if [[ -d "$name" && ("${name##*.}" != ${projectFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
It works also.
I want to keep filter xcworkspace and xcodeproj.
Someone can help me?
Finaly, I found result by myself.
#!/bin/bash
workspaceFile="xcworkspace"
projectFile="xcodeproj"
path=$1
fileList=()
projectList () {
for name in "$path"/*; do
if [ -d "$name" ] && [ "${name##*.}"x = ${workspaceFile}x ]; then
fileList+=(${name})
elif [ -d "$name" ] && [ "${name##*.}"x = ${projectFile}x ]; then
fileList+=(${name})
elif [ -d "$name" ]; then
path=$name
projectList
fi
done
}
projectList
for name in ${fileList[#]}; do
echo "xcode project: $name"
done
I have to find a way to have my script read from one of these three options:
a file argument
standard input
a previously established environment variable
Here's what I currently have:
#!/bin/bash
key=$1
[ $# -ge 1 -a -f "$2" ] && input="$2" || [ -f "$INPUT" ] && input="$INPUT" || input="-"
echo $input
Only the environment variable refuses to work, the rest works fine.
I've tried using the export INPUT="pathnametofile" before but it doesn't make any difference, I end up with the shell asking me to enter info as if I called on cat.
The problem in your script
Your attemp is not working due to the way the shell processes a Lists of Commands:
‘&&’ and ‘||’ have equal precedence.
AND and OR lists are executed with left associativity.
Your sentence:
[ $# -ge 1 -a -f "$2" ] && input="$2" || [ -f "$INPUT" ] && input="$INPUT" || input="-"
does the same as follows:
[ $# -ge 1 -a -f "$2" ] && input="$2"
[ $? -eq 0 ] || [ -f "$INPUT" ]
[ $? -eq 0 ] && input="$INPUT"
[ $? -eq 0 ] || input="-"
Now yo may see why your unexpected behaviour.
A better attempt grouping commands
{ [ $# -ge 1 -a -f "$2" ] && input="$2"; } || { [ -f "$INPUT" ] && input="$INPUT"; } || input="-"
Now, due to precedence, the first group is not needed at all:
[ $# -ge 1 -a -f "$2" ] && input="$2" || { [ -f "$INPUT" ] && input="$INPUT"; } || input="-"
Furthermore, unless you have set the positional parameters by hand, you can remove the first check (after all, if $2 is emtpy, -f "" fails the same).
[ -f "$2" ] && input="$2" || { [ -f "$INPUT" ] && input="$INPUT"; } || input="-"
An alternative with the if conditional construct
if [ -f "$2" ]; then
input=$2
elif [ -f "$INPUT" ]; then
input=$INPUT
fi
echo "${input:=-}"
untested, but you'll probably have better luck with if commands, and test that the variable is not empty:
if [ $# -ge 1 -a -f "$2" ]; then
input="$2"
elif [ -n "$INPUT" -a -f "$INPUT" ]; then
input="$INPUT"
else
input="-"
fi
I am trying to write a script but it is giving the above error
if [ [ [ "$1" != "abc" ] && [ "$1" != "def" ] ] || [ [ "$2" != "1" ] && [ "$2" != "0" ] ] ];
then
echo "Hello World"
fi
Be careful with && and ||. You can simplify it to this in BASH:
if [[ "$1" != "abc" && "$1" != "def" ]] || [[ "$2" != "1" && "$2" != "0" ]];
then
echo "Hello World"
fi
I need a logic to implement the following logic in unix
if ( $a !="xyz" || $d !="abc" ) && ( $b= $c))
then
echo "YES WORKING"
fi
I tried below code not working
if [ [ [ $a != "xyz" ] -o [ $d != "abc" ] ] -a [ "$b" = "$c" ] ]
then
echo "YES WORKING"
fi
getting error as
:[ :] unexpected operator/operand
You can do something like this:
[ $a != "xyz" -o $d != "abc" ] && [ "$b" = "$c" ] && echo "YES WORKING"
Your logic should work easy in shells supporting [[ ]]:
if [[ ($a != "xyz" || $d != "abc") && $b = "$c" ]]; then
echo "YES WORKING"
fi
Although there's a way for those that doesn't:
if ([ ! "$a" = "xyz" ] || [ ! "$d" = "abc" ]) && [ "$b" = "$c" ]; then
echo "YES WORKING"
fi
But that's still inefficient since you'd be summoning subshells, so use { } but the syntax is a little ugly:
if { [ ! "$a" = "xyz" ] || [ ! "$d" = "abc" ]; } && [ "$b" = "$c" ]; then
echo "YES WORKING"
fi
Suppose I am writing the following in a bash script:
if [ -z $a ] || [ -z $b ] ; then
usage
fi
It works but I would like to write it with short-circuiting as follows:
[ -z $a ] || [ -z $b ] || usage
Unfortunately it does not work. What am I missing ?
You want to execute usage in case either 1st or 2nd condition are accomplished. For that, you can do:
[ -z $a ] || [ -z $b ] && usage
Test:
$ [ -z "$a" ] || [ -z "$b" ] && echo "yes"
yes
$ b="a"
$ [ -z "$a" ] || [ -z "$b" ] && echo "yes"
yes
$ a="a"
$ [ -z "$a" ] || [ -z "$b" ] && echo "yes"
$
You could make use of the following form:
[[ expression ]]
and say:
[[ -z "$a" || -z "$b" ]] && usage
This would execute usage if either a or b is empty.
Always quote your variables. Saying
[ -z $a ]
if the variable a is set to foo bar would return an error:
bash: [: foo: binary operator expected