I have a -d option in a bash script but I dont what it does
cp -r ${version} ${version}tm
[ -d "latest-oi" ] rm latest-oi #line 35
[ -d "latest-tm" ] rm latest-tm #line 36
ln -sf "${version}" latest-oi
ln -sf "${version}tm" latest-tm
and when I execute the script I have this error message, I don't know why
./script.sh: line 35: [: missing `]'
./script.sh: line 36: [: missing `]'
I would like to know what -d means and what it does and why there is an error when the script is executed, Thanks
I don't see any -d option to your bash, but to the command [. See man test for this command. If you want to have two commands in the same line, you have use a command separator between them. Valid command separators are a newline, a ;, a && or a ||.
If you write a
[ -d "latest-oi" ] && rm latest-oi
it means that the rm is executed if [ returns exit code zero. Another way to write it would be
test -d latest-oi && rm latest-oi
If you would use a || instead, the rm would be executed whenever [ returns non-zero exit code.
Related
I am trying to script my SCREEN access and automate as much as possible my connection to my bastion host.
here my bash code:
#!/bin/bash
# set TERM to xterm-256color
export TERM=xterm-256color
# here we source bashrc
. .bashrc
# Detecting Command Line Arguments
if [ "$1" != "" ]; then
# check if the screen argument exist
if ! screen -list | grep -q "$1"; then
# create screen with new argument
screen -S $1
# At this point, argument is not found on screen
else
# Create it with argument specified.
screen -x $1
# Detecting if default screen exist
elif [[ ! screen -list | grep -q "myscreen" ]]; then
# no default screen exist, Create it !
screen -S myscreen
else
# attache to the default screen
screen -x myscreen
fi
there the output:
$ ./myscreen.sh test123
./myscreen.sh: line 18: syntax error near unexpected token `elif'
./myscreen.sh: line 18: `elif ! screen -list | grep -q "myscreen" ; then'
I tried also to [[ ! EXPR ]] no much better.
any one have a idea?
I reviewed your script and saw that it is missing a fi before the elif. Of course, I write bash code everyday, so this was easy for me to spot. You can use a bash syntax checker to help review your scripts (www.shellcheck.net).
Here's the results provided by that site:
$ shellcheck myscript
Line 8:
if [ "$1" != "" ]; then
^-- SC1009: The mentioned syntax error was in this then clause.
Line 10:
if ! screen -list | grep -q "$1"; then
^-- SC1046: Couldn't find 'fi' for this 'if'.
^-- SC1073: Couldn't parse this if expression. Fix to allow more checks.
Line 18:
elif [[ ! screen -list | grep -q "myscreen" ]]; then
^-- SC1047: Expected 'fi' matching previously mentioned 'if'.
^-- SC1072: Unexpected keyword/token. Fix any mentioned problems and try again.
$
You’re missing a fi statement to close out your internal if-else:
if
if
...
else
...
fi # You were missing this line
elif
...
else
...
fi
I want to compare two directories in a conditional.
if [ rsync -ai --dry-run dir1/ dir2/ ]; then
echo "Different!"
fi
However, I'm getting an error.\
./test.sh: line 44: [: too many arguments
How do I fix this error and get the conditional to echo if and only if the directories are different?
Note, rsync works as expected without the conditional.
rsync -ai --dry-run dir1/ dir2/
returns null when dir1 and dir2 are the same. And a non-null value otherwise.
What goes in [ ] is a test expression, not a command. Something like [ 5 -gt 4 ] or [ "foo" = "bar" ]. That rsync command doesn't make any sense as an expression, so you get a (not terribly clear) error.
It's possible capture the output of a command with "$( )", and test to see if that's blank with the -n test operator: if [ -n "$(rsync ...)" ], but there's actually a better way here. What goes after if is itself a command. [ is a really common command to use there, but you can use any command (or pipeline, or whatever) there. Essentially, it's "if this command succeeds, then..." So you can do this:
if rsync -ai --dry-run dir1/ dir2/ | grep -q "."; then
This feeds the output of the rsync command to grep, searching for "." (a pattern matching any character, i.e. is there any output), and the -q (quiet) option tells it not to bother printing matches, just exit with success status if there's at least one match.
[[ -n string ]] returns true if the length of string is non-zero, so you can do:
if [[ -n $(rsync -ai --dry-run dir1/ dir2/) ]]; then
echo "Different!"
fi
can you help me understand this line I found in a script:
trap "[[ -d ${temp_dir} ]] && rm -rf ${temp_dir}" EXIT
The way I understand is, the trap command waits for EXIT signal and upon that, it removes the directory, if it exists.
Is this correct or can anybody educate me?
Your interpretation is correct, although there are two changes I would make to the code itself:
$temp_dir needs to be quoted in the command to ensure it works correctly for any valid directory name. Let's say the value of temp_dir is /tmp/some dir. As is, the trap command will be
[[ -d /tmp/some dir ]] && rm -rf /tmp/some dir
which is incorrect, as the parameter is expanded before the trap command sets the error handler. Add some quotes to fix it:
trap "[[ -d '${temp_dir}' ]] && rm -rf '${temp_dir}'" EXIT
Depending on when the value of temp_dir is set, you might consider putting the entire command in single quotes, so that temp_dir isn't expanded until the command is actually run:
trap '[[ -d $temp_dir ]] && rm -rf "$temp_dir"' EXIT
However, it's usually simpler to keep the handler as simple as possible. Define a function to call:
clean_up_temp () {
[[ -d $temp_dir ]] && rm -rf "$temp_dir"
}
and just call the function from the handler:
trap clean_up_temp EXIT
I'm creating a very simple bash script that will check to see if the directory exists, and if it doesn't, create one.
However, no matter what directory I put in it doesn't find it!
Please tell me what I'm doing wrong.
Here is my script.
#!/bin/bash
$1="/media/student/System"
if [ ! -d $1 ]
then
mkdir $1
fi
Here is the command line error:
./test1.sh: line 2: =/media/student/System: No such file or directory
Try this
#!/bin/bash
directory="/media/student/System"
if [ ! -d "${directory}" ]
then
mkdir "${directory}"
fi
or even shorter with the parent argument of mkdir (manpage of mkdir)
#!/bin/bash
directory="/media/student/System"
mkdir -p "${directory}"
In bash you are not allow to start a variable with a number or a symbol except for an underscore _. In your code you used $1 , what you did there was trying to assign "/media/student/System" to $1, i think maybe you misunderstood how arguments in bash work. I think this is what you want
#!/bin/bash
directory="$1" # you have to quote to avoid white space splitting
if [[ ! -d "${directory}" ]];then
mkdir "$directory"
fi
run the script like this
$ chmod +x create_dir.sh
$ ./create_dir.sh "/media/student/System"
What the piece of code does is to check if the "/media/student/System" is a directory, if it is not a directory it creates the directory
I would like to execute a command like this:
#!/bin/sh
`which rvmsudo` `which program` argument
but I get this issue
/usr/bin/env: argument: No such file or directory
Make sure, all of the which statements return valid:
#!/bin/bash
RVMSUDO=`which rvmsudo`
test -z "$RCMSUDO" && exit 1
PROGRAM=`which program`
test -z "$PROGRAM" && exit 2
$RVMSUDO $PROGRAM argument