Understanding script to check if file exists or not - bash

I have below command to check if file exists or not and create it if it not available:
if test "${LOG_FILE:=}x" != "x"; then
touch $LOGAP
exit_code=$?
fi
Please help me in understanding this script, how the test condition "${LOG_FILE:=}x" != "x" is used for checking if exixts or not. I am using bash shell.

Basic idea
The script checks if $LOG_FILE variable is set. If it is, it touches the file with name stored in $LOGAP.
Explanation
Let's split it:
test == if
So
if test "${LOG_FILE:=}x" != "x"; then
is the same as
if [ "${LOG_FILE:=}x" != "x" ]; then
Let's do one test:
LOG_FILE="FILE_TEST"
echo "${LOG_FILE:=}x"
will output
FILE_TESTx
So what it is done is a checking of variable LOG_FILE being set or not. If it is set,
[ "${LOG_FILE:=}x" != "x" ]
will be
[ "FILE_TESTx" != "x" ]
which is true.
If LOG_FILE is not set,
[ "${LOG_FILE:=}x" != "x" ]
will be
[ "x" != "x" ]
which is false.
That is to say x is something to start with. You could change it to
[ "${LOG_FILE:=}HELLO_MY_NAME_IS_BLABLA" != "HELLO_MY_NAME_IS_BLABLA" ]
Finally, you have a
touch $LOGAP
which will touch (create a file if not created, update modified date if already exists). It also requires the variable $LOGAP to be set.
Have to say that the fastest way to check if a file exists is this:
if [ ! -f /tmp/foo.txt ]; then
...
fi

Related

shell script if condition giving error message in openshift platform . if[ == ] : not found [No such file or directory ]

I've implemented script like below:
podName=someValue ; // Here value is dynamic (empty or non empty)
if[ $podName == " "] then
echo "Empty"
Even though I got empty an output but still could see:
if[ == ] : not found [No such file or directory ]
error message while running the script.
Seems like there is a small formatting issue which is causing this error. This should be the correct code.
podName=someValue
if [ "$podName" == " " ]; then
echo "Empty"
fi
You can check if the string is empty in bash / sh like this (some containers don't have bash shell):
podName="someValue"
if [ -z "$podName" ]; then
echo "Empty"
fi
or:
podName="someValue"
if [ "$podName" = "" ]; then
echo "Empty"
fi
The following syntax works only in bash [ "$podName" == "" ]

How can I ensure the relevant command is run based on arguments passed in BASH?

I'm writing my first bash script that will do some visual testing using wraith. I've stripped down the code to make it easier to read.
What I'm trying to write:
- The BASH command accepts an argument - 1, 2 or 3. i.e. regressiontest 1
- server will be assigned the argument passed
- alias config will be assigned to wraith capture configs/capture-staging-1.yaml, wraith capture configs/capture-staging-2.yaml or
wraith capture configs/capture-staging-3.yaml
- The echo statement is written to a txt file.
The script works as expected. The only issue is:
If run regressiontest 1, all good, runs wraith capture configs/capture-staging-1.yaml as expected.
I run regressiontest 2, I would expect it to run wraith capture configs/capture-staging-2.yaml but seems to run wraith capture configs/capture-staging-1.yaml again.
It seems to be running using the previous config file. If I close and open terminal again, it works as expected but if I run the same command with a different argument consecutively it seems to always run the first command I use.
What am I doing wrong?
I'm new to BASH scripts and am having trouble googling to find an answer
function regressiontest {
regressionfolder=~/path/to/folder
cd $regressionfolder
alias config
if [ $# -eq 0 ]; then
echo "No arguments provided - USAGE: regressiontest <server>"
return 0
else
server=$1
fi
if [ $server != 1 ] && [ $server != 2 ] && [ $server != 3 ]; then
echo "Visual Regression Testing argument invalid - USAGE: regressiontest <server>"
return 0
elif [ $server == 1 ]; then
server="1"
alias config='wraith capture configs/capture-staging-1.yaml'
elif [ $server == 2 ]; then
server="2"
alias config='wraith capture configs/capture-staging-2.yaml'
elif [ $server == 3 ]; then
server="3"
alias config='wraith capture configs/capture-staging-3.yaml'
fi
echo "https://website-staging-$server/" > data/server.txt
config
}
Any help would be much appreciated.
Thanks, All
Moe
You are thinking right, but making things harder than need be. Your initial part of the script is fine, though I would validate that the cd succeeds, e.g.
regressionfolder=~/path/to/folder
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
(note: a return of 1 generally indicates error and always double-quote your variables)
After your check on "$server" != 1 ... all you need to do is set your alias with $server as the number. No additional if ... elif ... are required, e.g.
if [ "$server" != 1 ] && [ "$server" != 2 ] && [ "$server" != 3 ]; then
echo "Visual Regression Testing argument invalid - USAGE: regressiontest <server>"
return 1
fi
alias config="wraith capture configs/capture-staging-$server.yaml"
config
}
(note: always double-quote variables withing [...])
Eliminate the alias
There is no need for the alias, you can simply run:
wraith capture configs/capture-staging-$server.yaml
Putting it altogether, you could do something similar to:
function regressiontest {
regressionfolder="$HOME/path/to/folder"
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
if [ $# -eq 0 ]; then
echo "No arguments provided - USAGE: regressiontest <server>"
return 1
else
server=$1
fi
if [ "$server" != 1 ] && [ "$server" != 2 ] && [ "$server" != 3 ]; then
printf "Visual Regression Testing argument invalid - "
printf "USAGE: regressiontest <server>\n"
return 1
fi
wraith capture "configs/capture-staging-$server.yaml"
}
(note: also the use of "$HOME" instead of ~. While ~ will expand on the command line, you will quickly run into problems using it within scripts)
Use a case Statement
A shorter more condensed version of your function using case ... esac would probably be a bit better, e.g.
function regressiontest {
regressionfolder="$HOME/path/to/folder"
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
case "$server" in
[123] ) wraith capture "configs/capture-staging-$server.yaml";;
* ) printf "Visual Regression Testing argument invalid - "
printf "USAGE: regressiontest <server>\n"
return 1;;
esac
}
I don't think you want to declare aliases, but store commands for later execution; just remove the "alias" from alias config='…' and at the end call it via $config.

What does [ "$var" ] && $var do?

I was going through a codebase and came across the following piece of code in a shell script:
./some_script.sh
errcode=$?
if [ "$errcode" != 0 ]; then
[ "$SCRIPT_PATH" ] && $SCRIPT_PATH do_something
fi
SCRIPT_PATH is an environment variable which expands to the path of a script (say /usr/bin/abc.sh). However, I do not understand what the code in the if loop does. What does [ "$SCRIPT_PATH" ] do? Is there any use of it or was this just something written incorrectly? Only thing I can think of is that it was supposed to be [ -f "$SCRIPT_PATH" ] to check if file exists before running it, but I'm not sure anymore.
Any idea what else this could be doing?
It runs the program in SCRIPT_PATH if it is not empty or unset (because that's what the [ one_arg ] test does.)
It's a shorthand for the following:
if [ "$errcode" != 0 ]; then
if [ "$SCRIPT_PATH" ]; then
$SCRIPT_PATH do_something
fi
fi
It works by abusing the way chained conditions "short circuit" in an if statement.
Whether this is a good idea is … debatable.

Running script conditionally does not work in travis.yml, why?

The following causes travis to not build at all. When I try to validate the travis.yml file, it complains that the line just above the if statement is missing a - character at column 3, but the error has to do with the if statement below.
Do I have to move the if statement out to a script?
# Deploy
after_success:
- ./tools/docker-push-container.sh
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
You're making some assumptions about YAML syntax that are causing you problems. If you "exend" a line of YAML by indenting subsequent lines, like this:
- The quick brown fox
jumped over the
lazy dog.
It is exactly like you instead wrote this:
- The quick brown fox jumped over the lazy dog.
This means that your shell fragment, which you've written as:
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Actually becomes:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then ./.travis/success_message.sh fi
And if you try run that line in the shell, you get:
sh: -c: line 1: syntax error: unexpected end of file
If you want to include a multi-line shell script in your YAML document, your best bet is probably to use the verbatim block operator, |, like this:
- |
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Which will result, as intended, in:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Alternatively, you could just make proper use of semicolons:
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh;
fi
Note the new ; before the terminal fi. This results in:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then ./.travis/success_message.sh; fi
...which is perfectly valid shell syntax.
I tried the above solution by larsks but, it did not work for me and could be because in bash when you use && and || you need to separate the conditions.
I had the following (according to above solution)
- if [ $TRAVIS_PULL_REQUEST == false && $TRAVIS_BRANCH == "development" ]; then
echo "# Bump version and flyway migrate db";
else
echo "Skip version increment!";
fi
And I also checked the .travis.yml in Travis Lint and it shows as valid but, according to bash the above can be separated as shown below, also mentioned in this SO Question and I changed to following
- if [ $TRAVIS_PULL_REQUEST == false ] && [ $TRAVIS_BRANCH == "development" ]; then
echo "# Bump version and flyway migrate db";
else
echo "Skip version increment!";
fi
And travis build worked. It kind of make sense because above is valid way to use && and || in bash. Just sharing in case someone else come across a similar issue.
Raf's solution worked for me with separating the conditionals with []
[ $TRAVIS_PULL_REQUEST == false ] && [ $TRAVIS_BRANCH == "develop" ];
None of the suggested workarounds worked for me, I used this instead:
- if [[ ( "$TRAVIS_OS_NAME" == "osx" ) && ( "$TOXENV" == "py36" ) ]]; then brew update; fi

If condition not work regular in bash

Code
if [ $setup==="y" ]
then
echo "kurulum:"$setup
exit
full_dir=$full_dir"/public"
else
echo "Sub-Public folder is exist? [public,web]"
read folder_extend
if [ $folder_extend ]
then
full_dir=$full_dir"/"$folder_extend
fi
fi
Setup param $setup view as "n" after run sh but still condition firts part run. Where wrong code ?
Thanks.
Change it to:
if [ "$setup" = "y" ]
then
echo "kurulum:"$setup
exit
full_dir=$full_dir"/public"
else
echo "Sub-Public folder is exist? [public,web]"
read folder_extend
if [ "$folder_extend" ]
then
full_dir=$full_dir"/"$folder_extend
fi
fi
It should just be a single =, and you need spaces around it. You should also quote variables in most contexts, in case they contain spaces.

Resources