Bash file shows "ln: command not found" - linux

I'm trying to create a bash script to setup my development environment. The script is running as root but I get the error line 11: ln: command not found
#!/bin/bash
#Require script to run as root - doesn't work - syntax error in conditional expression: unexpected token `;'
#if [[ $(/usr/bin/id -u) -ne 0]]; then
# echo "Script must be run as root";
# exit;
#fi
#PHPMyAdmin
PATH="/etc/apache2/sites-available/phpmyadmin.local";
if [ ! -a PATH ]; then
ln -s /home/user/Ubuntu\ One/htdocs/vhosts/phpmyadmin.local PATH;
a2ensite phpmyadmin.local;
fi

PATH=...
Congratulations, you've clobbered how the shell finds commands. Don't do that.

PATH tells the shell where to look for commands. In your case, it looks for ln somewhere in /etc and predictably doesn't find it there.
You should use a different name.

Related

Bash syntax issue, 'syntax error: unexpected "do" (expecting "fi")'

I have a sh script that I am using on Windows and Mac/Linux machines, and seems to work with no issues normally.
#!/bin/bash
if [ -z "$jmxname" ]
then
cd ./tests/Performance/JMX/ || exit
echo "-- JMX LIST --"
# set the prompt used by select, replacing "#?"
PS3="Use number to select a file or 'stop' to cancel: "
# allow the user to choose a file
select jmxname in *.jmx
do
# leave the loop if the user says 'stop'
if [[ "$REPLY" == stop ]]; then break; fi
# complain if no file was selected, and loop to ask again
if [[ "$jmxname" == "" ]]
then
echo "'$REPLY' is not a valid number"
continue
fi
# now we can use the selected file, trying to get it to run the shell script
rm -rf ../../Performance/results/* && cd ../jmeter/bin/ && java -jar ApacheJMeter.jar -Jjmeter.save.saveservice.output_format=csv -n -t ../../JMX/"$jmxname" -l ../../results/"$jmxname"-reslut.jtl -e -o ../../results/HTML
# it'll ask for another unless we leave the loop
break
done
else
cd ./tests/Performance/JMX/ && rm -rf ../../Performance/results/* && cd ../jmeter/bin/ && java -jar ApacheJMeter.jar -Jjmeter.save.saveservice.output_format=csv -n -t ../../JMX/"$jmxname" -l ../../results/"$jmxname"-reslut.jtl -e -o ../../results/HTML
fi
I am now trying to do some stuff with a Docker container and have used a node:alpine image, as the rest of my project is NodeJS based, but for some reason the script will not run in the Docker container giving the following -
line 12: syntax error: unexpected "do" (expecting "fi")
How can I fix that? The script seems to be working for every system it's been run on so far, and not thrown up any issues.
The error message indicates that the script is executed as '/bin/sh', and not as /bin/bash. You can see the message with '/bin/sh -n script.sh'
Check how the script is invoked. On different systems /bin/sh is symlinked to bash or other shell that is less feature rich.
In particular, the problem is with the select statement, included in bash, but not part of the POSIX standard.
Another option is that bash on your docker is set to be POSIX compliant by default
#dash-o was correct, and adding -
RUN apk update && apk add bash
to my dockerfile added bash into the container and now it works fine :)

Newbie: Script to change directories

The following is a snippet of a larger script I'm attempting. I just want this part to recognize the argument is a directory and then cd to that directory: i.e ./larj /etc.
#!/bin/ksh
# Filename: larj.sh
if [ $# -gt 1 ]; then
echo "0 or 1 arguments allowed."
exit
fi
if [ -f "$1" ]; then
echo "directory only."
exit
else
if [ -d "$1" ]; then
cd $1
fi
fi
When I run the script with /etc as the argument, it appears nothing happens; it stays in the same directory with no error.
Anyone have any suggestions how to get it to change directories?
Thanks
The cd is taking place within the script's shell.
When the script ends, it's shell exits, and you return to the directory before running the script. In order to change the directory you can
mkdir testdir
. ./your_script.sh testdir
At the end of the script you will be moved at directory testdir.
The problem why you cd can't work is that cd executes in the sub-shell when you execute the script as ./larj /etc. So when you execute the script, it changes the working directory of the subshell and has no impact on the current shell.
So you can execute it as . ./larj /etc.
Refer to Why doesn't “cd” work in a bash shell script?.

Sourcing files in shell script vs sourcing on command line

I have the problem that my shell script is not acting exactly the same as my manual typing into a console. I am attempting to find and source some setup files in a shell script as follows:
#!/bin/bash
TURTLE_SHELL=bash
# source setup.sh from same directory as this file
_TURTLE_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_TURTLE_SETUP_DIR/turtle_setup.sh"
This bash file calls a .sh file:
#!/bin/env sh
_TURTLE_ROS_SETUP_DIR=$_TURTLE_SETUP_DIR/../devel
if [ -z "$TURTLE_SHELL" ]; then
TURTLE_SHELL=sh
fi
if [ -d "$PX4_FIRMWARE_DIR/integrationtests" ]; then
if [ -f "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" ]; then
. "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" "$PX4_FIRMWARE_DIR"
fi
fi
if [ "$TURTLE_SHELL" = "bash" ]; then
if [ -f "$_TURTLE_ROS_SETUP_DIR/setup.bash" ]; then
source $_TURTLE_ROS_SETUP_DIR/setup.bash
fi
else
if [ "$TURTLE_SHELL" = "sh" ]; then
if [ -f "$_TURTLE_ROS_SETUP_DIR/setup.sh" ]; then
source $_TURTLE_ROS_SETUP_DIR/setup.sh
fi
fi
fi
The line in question is:
. "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" "$PX4_FIRMWARE_DIR"
I have made sure that this code is actually running and that my environment variables are correct. If I run this command on the command line everything works well. However, the same is not true when the file is sourced via shell script. Why is this? Is there something different about the environment of a shell script that is different from a command line. Also, how can I fix this problem?
Edit:
I am sourcing either the .bash or the .sh scale, depending upon which shell I am using.
Edit 2:
I am sourcing this script. Thus, everything is run in my default bash terminal, and it is all run within the same terminal and not a terminal spawned from a child process. Why is the script not sourcing setup_gazebo_ros.bash within the current shell?
It's the same reason why you source the env script and not run it. When you run the script it runs in a new shell and the variables are not transferred back to the parent shell.
To illustrate
$ cat << ! > foo.sh
> export foo='FOO'
> !
$ chmod +x foo.sh
$ ./foo.sh
$ echo $foo
$ source ./foo.sh
$ echo $foo
FOO

Basic Bash backup script

I'm still learning how to program in bash and for practice i'm trying to do a "backup script" (quotes because I know this isn't a proper backup) here is the code:
#|/bin/bash
sudo mkdir /home/lucas/bkp
echo "Type the path for the directory you want do save"
read directory
if [-d $directory]; then
sudo cp -R $directory /home/lucas/bkp/
else
echo "Path not found"
fi
But I get an error saying the path saved on variable does not exists and doing the same commands by "hand", directly on the shell everything is fine. Here is the error:
lucas#lucas-Linux:~$ sudo sh ./ex.sh
Type the path for the directory you want do save
/home/lucas/git/
./ex.sh: 7: ./ex.sh: [-d: not found
Path not found
You need to put spaces in your condition, like this :
if [ -d $directory ]; then

Bash: Why can't I assign an absolute path to a variable?

I am trying to assign an absolute path to a variable in Bash:
#!/bin/bash
DIR= "/home/foobar"
echo "$DIR/test"
The output:
./test.sh: line 2: /home/foobar: Is a directory
/test
I don't understand what is happening there, please help me.
Remove the space before "/home/foobar":
#!/bin/bash
DIR="/home/foobar"
echo "$DIR/test"
Try in another shell.
#!/bin/sh
DIR='/home/foobar'
echo "$DIR/test"
Or if you want to check if the variable is getting initialized or not using this.
#!/bin/sh
DIR='/home/foobar'
[ -z "$DIR" ] && echo "Variable not declared" && exit
echo "$DIR/test"
The general syntax is
[ assignment=value ... ] command arguments
so you are doing an assignment of DIR= and running the command /home/foobar -- which of course isn't a valid command, but a directory; hence the error message.
Try this:
DIR=/home/foobar bash -c 'echo "DIR is \"$DIR\""' # DIR is "/home/foobar"
echo "done. DIR is now \"$DIR\"" # DIR is now ""
and you will see that DIR is assigned only during the first command, then lost.
To set it for the remainder of your script, you can do
DIR=/home/foobar
echo "DIR is now $DIR"
and if you want to expose it to child processes, you can add an export:
DIR=/home/foobar
bash -c 'echo "Before export: DIR is \"$DIR\""' # DIR is ""
export DIR
bash -c 'echo "After export: DIR is \"$DIR\""' # DIR is "/home/foobar"

Resources