directorylist in shell sh-Script - linux

i have a sh-Script with:
#!/bin/sh
dirs=( $(find . -maxdepth 1 -type d -printf '%P\n') )
echo "There are ${#dirs[#]} dirs in the current path"
let i=1
for dir in "${dirs[#]}"; do
echo "$((i++)) $dir"
done
answer=2
echo "you selected ${dirs[$answer]}!"
But i got the error:
symfonymenu.sh: Syntax error: "(" unexpected (expecting "}")
its the line ...dirs=
I like to echo all available directories in a folder that user can select it in a prompt interface.

You use features from the bash shell, so you should execute the script in bash. Change the first line to:
#!/bin/bash
/bin/sh can be any POSIX-compatible shell, for example on Ubuntu it's dash.

That's a bash script so you should make sure that you're running it with bash. Call it as bash script.sh. Also you should start your index from 0 not 1: let i=0.

Related

echo: command not found. in shell script

echo 'Working Space'
read dirname #directory
if [ -n "$dirname" ]
...
fi
for dir in *
do
newname=`echo $dir | tr "[a-z] [A-Z]" "[A-Z] [a-z]"`
mv $dir $newname
done
~
~
~
~
~
~
I'm new to shell script. I have some problem with command echo.
It's my school assignment and my assistant gave me the template code.
However the first line which contains command 'echo' he gave got me an error.
./utol.sh: line 1: echo: command not found
I checked path /bin whether it contains echo command, and simple command like 'echo hi' works well in my terminal, so I'm guessing this problem is not related with echo itself but other lines.
Can anybody help me? Thanks.

Unable to exit shell script when using exec command

I have one main script(deploy_test.sh) which loops through files using find command and executes several other shell scripts. The main script does not exit even if other shell encounters failure. I used several options at the start of script but still iam unable to exit and script is continuing till the end.
deploy_test.sh
#!/usr/bin/env bash
set -euo pipefail
shopt -s execfail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Do you want to Continue: [Yes/No]"
read action
if [ $action = "Yes" ]
then
echo "Executing scripts"
find ${SCRIPT_DIR}/folder2 -type f -name '*.sh' -exec bash {} \;
echo $?
echo "This should also not be printed"
else
echo "nothing"
exit 1
fi
My folder2 has 2 .sh files (1.sh and 2.sh)
1.sh(have some special character at the end of script)
#!/usr/bin/env bash -eu
echo "hi iam in 1.sh and i have error in this file"
`
2.sh
#!/usr/bin/env bash -eu
echo "hi iam in 2.sh and i have no error in this file"
Ouptut when i execute script
(deploy) CSI-0048:test_test smullangi$ ./deploy_test.sh
Do you want to Continue: [Yes/No]
Yes
Executing scripts
hi iam in 1.sh and i have error in this file
/Users/smullangi/Desktop/test_test/folder2/1.sh: line 4: unexpected EOF while looking for matching ``'
/Users/smullangi/Desktop/test_test/folder2/1.sh: line 5: syntax error: unexpected end of file
hi iam in 2.sh and i have no error in this file
0
This should also not be printed
I expected this script to exit after encountering error in 1.sh file which had special character. But whatever options I tried the script is not exiting after it encounters error.
Any help is really appreciated. I am executing this on macbook (macos catalina v10.15.3) with bash version(3.2.57(1)-release)
#UPDATE1:
Also i feel script is not executing at all. If there are no errors in the script then also it exits. In short i feel my scripts in folder1/folder2 is not getting executed after modyfing code as per Phillippe suggestions
#!/usr/bin/env bash
set -euo pipefail
shopt -s execfail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Do you want to Continue: [Yes/No]"
read action
if [ $action = "Yes" ]
then
echo "Executing scripts"
find ${SCRIPT_DIR}/folder2 -type f -name '*.sh' -exec false bash {} +
#find ${SCRIPT_DIR}/folder2 -type f -name '*.sh' -exec bash {} \;
echo $?
echo "This should also not be printed"
else
echo "nothing"
exit 1
fi
Output
(deploy) CSI-0048:test_test smullangi$ ./deploy_test.sh
Do you want to Continue: [Yes/No]
Yes
Executing scripts
find does not always exit with error code when commands it runs give error:
find ${SCRIPT_DIR}/folder1 -type f -exec false {} \;
Above find command itself runs successfully even though every command it runs gives error.
Following find gives error:
find ${SCRIPT_DIR}/folder1 -type f -exec false {} +
To have error handling of each script, you can do
cd ${SCRIPT_DIR}/folder1
for script in ./*.sh; do
$script
done
I did not find any elegant solution using exec. So i used xargs in find command and it is working perfectly fine. Shell exits with appropriate error message. I used this as my reference https://unix.stackexchange.com/questions/571215/force-xargs-to-stop-on-first-command-error
#!/usr/bin/env bash
set -euo pipefail
shopt -s execfail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Do you want to Continue: [Yes/No]"
read action
if [ $action = "Yes" ]
then
echo "Executing scripts"
find ${SCRIPT_DIR}/folder2 -type f -name '*.sh' | xargs -I {} sh -c 'bash "$1" || exit 255' sh {}
echo $?
echo "This should also not be printed"
else
echo "nothing"
exit 1
fi

What's the difference between the parameters got by read and $1

echo -n "*.xcodeproj directory: ";
read fileDirectory;
echo -n $fileDirectory;
fileExtension="pbxproj";
find $fileDirectory -name "*.${fileExtension}";
It shows "find: XXXX"(fileDirectory) no such file or directory
However if I replace read fileDirectory by
fileDirectory=$1
It works.
So what's the difference?
$1 is the first argument passed to bash script or to a function inside the script
for example:
mybashfunction /dirtofind
inside the function if you write:
echo "$1"
It should print:
/dirtofind
Edit 1:
You must place the shebang in the beginning of you file
~$ cat a.sh
#!/bin/bash
echo -n "*.xcodeproj directory: ";
read fileDirectory;
echo -n $fileDirectory;
fileExtension="pbxproj";
find "$fileDirectory" -name "*.${fileExtension}";
~$ chmod +x a.sh
~$ ./a.sh
*.xcodeproj directory: /home
/home/home/leonardo/Qt/Tools/QtCreator/share/qtcreator/qbs/share/qbs/examples/cocoa-touch-application/CocoaTouchApplication.xcodeproj/project.pbxproj
/home/leonardo/Qt/Tools/QtCreator/share/qtcreator/qbs/share/qbs/examples/cocoa-application/CocoaApplication.xcodeproj/project.pbxproj
:~$
Works like charm here. Place the shebang
#!/bin/bash
Edit 2
Yes you can use eval. Your script will be like this:
#!/bin/bash
echo -n "*.xcodeproj directory: ";
read fileDirectory;
echo -n $fileDirectory;
fileExtension="pbxproj";
eval fileDirectory=$fileDirectory
find "$fileDirectory" -name "*.${fileExtension}";
read reads data from STDIN (by default), not from positional parameters (arguments).
As you are passing the data as first argument ($1) to the script, read would not catch it; it would catch the input you are providing interactively.
Just to note, you should quote your variable expansions to avoid word splitting and pathname expansion; these are unwanted in most cases.

Bash Script Variable

#!/bin/bash
RESULT=$(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
for i in $(RESULT);
do
echo "$i"
FILENAME="$(dirname $RESULT)"
done
I have a problem with the line FILENAME="$(dirname $RESULT)". Running the script in debugging mode(bash -x script-name), the ouput is:
test.sh: line 9: RESULT: command not found
For some reason, it can't take the result of the variable RESULT and save the output of dir command to the new variable FILENAME. I can't understand why this happens.
After lots of tries, I found the solution to save full path of finame and finame to two different variables.
Now, I want for each finame, find non-case sensitive of each filename. For example, looking for file image.png, it doesn't matter if the file is image.PNG
I am running the script
while read -r name; do
echo "$name"
FILENAME="$(dirname $name)"
BASENAME="$(basename $name)"
done < <(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
and then enter the command:
find . $FILENAME -iname $BASENAME
but it says command FILENAME and BASENAME not found.
The syntax:
$(RESULT)
denotes command substitution. Saying so would attempt to run the command RESULT.
In order to substitute the result of the variable RESULT, say:
${RESULT}
instead.
Moreover, if the command returns more than one line of output this approach wouldn't work.
Instead say:
while read -r name; do
echo "$name"
FILENAME="$(dirname $name)"
done < <(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
The <(command) syntax is referred to as Process Substitution.
for i in $(RESULT) isn't right.You can use $RESULT or ${RESULT}

Bash file shows "ln: command not found"

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.

Resources