line 1: ?#!/usr/bin/sh: not found when trying to execute a shell script - bash

I have a script called autoinstall:
#!/usr/bin/sh
echo "Installasi membutuhkan free space minimal 2MB, pastikan ada punya cukup space di router anda"
read -p "Anda yakin ingin melanjutkan installasi?(y/n) " -n 1 -r
echo ""
if [[ $REPLY = ^[Yy]$ ]]
then
cd /
cd /tmp/
tar -xvf OpenWrt_Angel_Beats_Edition_v1.3.3.tar -C /
chmod -R 744 /root/crt
chmod 744 /www/wget/wget_download.sh
chmod 744 /usr/bin/gsm
chmod 744 /usr/bin/profile
opkg update && opkg install elinks
cp /etc/rc.local /etc/rc.local.backup
cat > /etc/rc.local << END
#!bin/sh
# /etc/rc.local: Local system initialization script.
#
# Put any local startup commands in here. Also, if you have
# anything that needs to be run at shutdown time you can
# make an /etc/rc.d/rc.local_shutdown script and put those
# commands in there.
sh /www/wget/wget_download.sh > /dev/null 2>&1 &
exit 0
END
killall sh /www/wget/wget_download.sh
sh /www/wget/wget_download.sh > /dev/null 2>&1 &
echo "File backup /etc/rc.local.backup telah dibuat, gunakan file ini untuk mengembalikan konfigurasi rc.local anda yang dulu jika diperlukan"
echo "Installasi selesai. Jangan lupa di akun openvpn yang digunakan (/root/crt/xxx.ovpn) tambahkan baris ini:
script-security 2
up client-connect.sh"
else
echo ""
echo "Installasi dibatalkan"
fi
Every command that I put in the first line always gets the error above (line 1:xxx not found) and I'm sure I've typed in the correct command, even echo gives the error like that, how do I solve this?

There can be two problems here:
The file doesn't exist. Usually, for sh, the path is /bin/sh, so it should be #!/bin/sh
You're editing the file on Windows. Windows uses CR+LF as line ending. Unix (and Linux) uses just LF. So for Linux, the command reads "execute /bin/sh<CR> and sh<CR> doesn't exist.
Solution: When editing the file, make sure you use Unix line endings.

The file might have been edited with an editor that insert a Unicode BOM (Byte Order Mark).
Have a look to the first line contents with:
od -c autoinstall | head -1
or
hd -n 16 autoinstall
If you see unexpected characters before #!/usr/bin/sh, you might try one of the methods described here Using awk to remove the Byte-order mark to remove the BOM.

Related

Using Vim commands in a Bash Script

so im trying to create a bash script that runs on MAC command line to a remote server and uses some mv commands to move some files around but i also need it to open up a file and add a line to the top of the file and save it in the middle of the script heres what i have so far:
(this is adjusting permissions so i can edit the file)
chef-client -r xxxxxxredactedxxxxxxredacted
cd /xxx/postgresql/xx/main/
Sudo chmod -R 775 filenamehere
sudo chown -R postgres:postgres filenamehere
read -p 'Enter the IP: ' ip
echo "Enter the file name :"
read -r filename
echo "Type this below: host all all "$ip"/24 trust : "
read -r line
cd /etc/postgresql/12/main/
printf '1i\n%s\n.\nwq\n' "$line" | ed "$filename". <-- **this is the problem line**
^ this command gives me permission denied because of access, for some reason i can edit it with vim but not this command
its worth noting these commands arent ran through my pc so my ability to move files is somewhat limited, its ran through SSM ing into an IP of a test enviroment through my command line
Normally I manually VIM into the file and add a line to the top
Don't know if you're using echo to output the prompts because you didn't know about the -p read option or you wanted the new lines.
You could use command grouping to add a line at the top of your file.
read -p "Have you copied a file to the data shipper? (yes/no)"
if [ "$REPLY" == "yes" ]; then
read -p "Enter a variable: " VARIABLE
read -p "Enter a file name: " FILE
cd /var/xxxredacted////
cd /tmp/
sudo mv "$FILE" /varxxxredactedxxxxxxxx/drop
cd /var/redactedxxxxredactedxx/drop
sudo unzip "$FILE"
fi
read -p "Enter the file name:\n" FILENAME
read -p "Enter the line to be added:\n" LINE
{ echo $LINE; cat "$FILENAME"; } > "${FILENAME}.new"
mv "$FILENAME"{.new,}
sed could be used too, if the line had to go to a specific line :
# If \n is omnited, $LINE will just be inserted on
# line 1 instead of appending a new line
sed -i "${LINENB}s/$LINE\n/" $FILENAME

How to handle additional files when building and running a AUR package?

So I was just playing around and created this simple Shell script:
TestScript.sh
#!/bin/bash
read -p "read or write? " INP
if [[ "${INP}" == "write" ]]
then
read -p "Write your text: " TEXT
touch /usr/share/textfile.txt
echo "${TEXT}" >> /usr/share/textfile.txt
else
cat /usr/share/textfile.txt
fi
which of course can easily read and write into a file under /usr after gaining sudo priviliges:
sudo sh TestScript.sh
Based on this file I create a test PKGBUILD to install TestScript.sh via pacman later on:
PKGBUILD
# Maintainer: Your Name <youremail#domain.com>
pkgname='test-script'
pkgver=1
pkgrel=1
pkgdesc="AUR test package"
arch=('x86_64')
license=('custom')
source=('TestScript.sh')
md5sums=('SKIP')
package() {
mkdir -p "${pkgdir}/usr/bin"
cp "${srcdir}/TestScript.sh" "${pkgdir}/usr/bin/TestScript"
chmod +x "${pkgdir}/usr/bin/TestScript"
}
Followed by
makepkg
sudo pacman -U test-script-1-1-x86_64.pkg.tar.xz
I can run
TestScript
from the command line. But just as I thought, I am unable to write into /usr/share/textfile.txt .
I was searching the Arch-Wiki page up and down, but I couldn't find out how to handle this situation. I basically just want to have a location where I can properly read and write a file without messing up the user space.
Does anyone have an idea?

Running executable file with additional options or arguments

I'm writing a bash script Test.sh that aims to execute anotherscript (a linux executable file):
#!/bin/bash -l
mp1='/my/path1/'
mp2='/my/path2/anotherscript'
for myfile in $mp1*.txt; do
echo "$myfile"
"$mp2 $myfile -m mymode"
echo "finished file"
done
Notice that anotherscript takes as arguments $myfile and options -m mymode.
But I get the file not found error (says Test.sh: line 8: /my.path2/anotherscript: No such file or directory).
My questions are:
I have followed this question to get my bash script to run the executable file. But I'm afraid I still get the error above.
Am I specifying arguments as they should to execute the file?
I suggest you use
sh -c "$mp2 $myfile -m mymode"
instead of just
"$mp2 $myfile -m mymode"
#!/bin/bash -l
dir=`find /my/path1/ -name "*.txt"`
mp2='/my/path2/anotherscript'
for myfile in "$dir"; do
echo "$myfile"
"$mp2" "$myfile" -m mymode
echo "finished file"
done
Make sure anotherscript has execution right (chmod +x anotherscript).

Should this be done with bash script or automator or applescript?

I have bash command that contains a variable to a file which updates the firmware for a specific hardware and give it a serial number.
#!/bin/bash
fpath=$(dirname "$0")
ee_image=mlr-2000119.bin
sudo nvram tbt-options=4
sudo /usr/sbin/bless -mount / -firmware "$fpath/ThorUtilDevice.efi" -payload "$fpath/$ee_image" -options "-o -ej 1 -blast efi-apple-payload0-data"
sudo reboot now
I would like to create a file through automator or applescript that will create this same file but will automatically increase the ee_image bin file name by one. So that the end user doesn't always have to open the command file in text edit, make the change manually then save then execute the file..
Any help with this would be a God send.
The last line in your script sudo reboot now would make any sort of loop meaningless.
However, if you insist, use may a loop:
#!/bin/bash
fpath=$(dirname "$0")
for i in {2000119..3000119}; do
ee_image=mlr-${i}.bin
sudo nvram tbt-options=4
sudo /usr/sbin/bless -mount / -firmware "$fpath/ThorUtilDevice.efi" -payload "$fpath/$ee_image" -options "-o -ej 1 -blast efi-apple-payload0-data"
sudo reboot now
done
This would loop through mlr-2000119.bin to mlr-3000119. You can also consider passing an argument to the script in which case you can use your original script with the ee_image line as
ee_image=mlr-$1.bin
and invoke bash /path/to/your/script.sh 2000119
#devnull wrote:
The last line in your script sudo reboot now would make any sort of loop meaningless.
I believe that the reboot command is just like any other command. It should be echoed to a file rather than being run to generate the script for the end-user.
I think that a good idea would be to have a script that creates scripts.
This is similar to how many websites work. The script on the server can echo HTML, CSS, and JavaScript code for consumption by the web browser.
Here is an example:
#!/bin/bash
# set the path to the dir
dir=$(dirname $0)"/"
# set the path to the file that keeps track of the serial numbers
snFile="$dir""sn.txt"
# set the file name of the file to be generated
fileName="serialize"
# read the last serial number used
if [ -e "$snFile" ];
then
read lastSN < "$snFile"
else
lastSN="0"
fi
# increment the serial number
let "nextSN = $lastSN + 1"
echo "$nextSN" > "$snFile"
# create a path variable for the file being created.
generatedPath="$dir$fileName$nextSN.sh"
# generate the script
echo "#!/bin/bash" > "$generatedPath"
echo 'fpath=$(dirname "$0")' >> "$generatedPath"
echo '' >> "$generatedPath"
echo "ee_image=mlr-$nextSN.bin" >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo nvram tbt-options=4' >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo /usr/sbin/bless -mount / -firmware \"$fpath/ThorUtilDevice.efi\" -payload \"$fpath/$ee_image\" -options \"-o -ej 1 -blast efi-apple-payload0-data\" \' >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo reboot now' >> "$generatedPath"
# give the user some feedback
echo "generatedPath: $generatedPath"
If having your end-user run a bash script is good enough, then I think that you're almost done.
If you want to have an even better user interface and have a Mac application for the end-user to run, send me an email and I can help you with that.
kaydell#learnbymac.com

Bash syntax error: unexpected end of file

Forgive me for this is a very simple script in Bash. Here's the code:
#!/bin/bash
# june 2011
if [ $# -lt 3 -o $# -gt 3 ]; then
echo "Error... Usage: $0 host database username"
exit 0
fi
after running sh file.sh:
syntax error: unexpected end of file
I think file.sh is with CRLF line terminators.
run
dos2unix file.sh
then the problem will be fixed.
You can install dos2unix in ubuntu with this:
sudo apt-get install dos2unix
Another thing to check (just occured to me):
terminate bodies of single-line functions with semicolon
I.e. this innocent-looking snippet will cause the same error:
die () { test -n "$#" && echo "$#"; exit 1 }
To make the dumb parser happy:
die () { test -n "$#" && echo "$#"; exit 1; }
i also just got this error message by using the wrong syntax in an if clause
else if (syntax error: unexpected end of file)
elif (correct syntax)
i debugged it by commenting bits out until it worked
an un-closed if => fi clause will raise this as well
tip: use trap to debug, if your script is huge...
e.g.
set -x
trap read debug
I got this answer from this similar problem on StackOverflow
Open the file in Vim and try
:set fileformat=unix
Convert eh line endings to unix endings and see if that solves the
issue. If editing in Vim, enter the command :set fileformat=unix and
save the file. Several other editors have the ability to convert line
endings, such as Notepad++ or Atom
Thanks #lemongrassnginger
This was happening for me when I was trying to call a function using parens, e.g.
run() {
echo hello
}
run()
should be:
run() {
echo hello
}
run
I had the problem when I wrote "if - fi" statement in one line:
if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi
Write multiline solved my problem:
if [ -f ~/.git-completion.bash ]; then
. ~/.git-completion.bash
fi
So I found this post and the answers did not help me but i was able to figure out why it gave me the error. I had a
cat > temp.txt < EOF
some content
EOF
The issue was that i copied the above code to be in a function and inadvertently tabbed the code. Need to make sure the last EOF is not tabbed.
on cygwin I needed:-
export SHELLOPTS
set -o igncr
in .bash_profile . This way I didn't need to run unix2dos
FOR WINDOWS:
In my case, I was working on Windows OS and I got the same error while running autoconf.
I simply open configure.ac file with my NOTEPAD++ IDE.
Then I converted the File with EOL conversion into Windows (CR LF) as follows:
EDIT -> EOL CONVERSION -> WINDOWS (CR LF)
Missing a closing brace on a function definition will cause this error as I just discovered.
function whoIsAnIidiot() {
echo "you are for forgetting the closing brace just below this line !"
Which of course should be like this...
function whoIsAnIidiot() {
echo "not you for sure"
}
I was able to cut and paste your code into a file and it ran correctly. If you
execute it like this it should work:
Your "file.sh":
#!/bin/bash
# june 2011
if [ $# -lt 3 -o $# -gt 3 ]; then
echo "Error... Usage: $0 host database username"
exit 0
fi
The command:
$ ./file.sh arg1 arg2 arg3
Note that "file.sh" must be executable:
$ chmod +x file.sh
You may be getting that error b/c of how you're doing input (w/ a pipe, carrot,
etc.). You could also try splitting the condition into two:
if [ $# -lt 3 ] || [ $# -gt 3 ]; then
echo "Error... Usage: $0 host database username"
exit 0
fi
Or, since you're using bash, you could use built-in syntax:
if [[ $# -lt 3 || $# -gt 3 ]]; then
echo "Error... Usage: $0 host database username"
exit 0
fi
And, finally, you could of course just check if 3 arguments were given (clean,
maintains POSIX shell compatibility):
if [ $# -ne 3 ]; then
echo "Error... Usage: $0 host database username"
exit 0
fi
In my case, there is a redundant \ in the like following:
function foo() {
python tools/run_net.py \
--cfg configs/Kinetics/X3D_8x8_R50.yaml \
NUM_GPUS 1 \
TRAIN.BATCH_SIZE 8 \
SOLVER.BASE_LR 0.0125 \
DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
DATA.PATH_PREFIX ./afs/kinetics400 \ # Error
}
There is NOT a \ at the end of DATA.PATH_PREFIX ./afs/kinetics400
I just cut-and-pasted your example into a file; it ran fine under bash. I don't see any problems with it.
For good measure you may want to ensure it ends with a newline, though bash shouldn't care. (It runs for me both with and without the final newline.)
You'll sometimes see strange errors if you've accidentally embedded a control character in the file. Since it's a short script, try creating a new script by pasting it from your question here on StackOverflow, or by simply re-typing it.
What version of bash are you using? (bash --version)
Good luck!
Make sure the name of the directory in which the .sh file is present does not have a space character. e.g: Say if it is in a folder called 'New Folder', you're bound to come across the error that you've cited. Instead just name it as 'New_Folder'. I hope this helps.
Apparently, some versions of the shell can also emit this message when the final line of your script lacks a newline.
In Ubuntu:
$ gedit ~/.profile
Then, File -> Save as and set end line to Unix/Linux
I know I am too late to the party. Hope this may help someone.
Check your .bashrc file. Perhaps rename or move it.
Discussion here: Unable to source a simple bash script
For people using MacOS:
If you received a file with Windows format and wanted to run on MacOS and seeing this error, run these commands.
brew install dos2unix
sh <file.sh>
If the the script itself is valid and there are no syntax errors, then some possible causes could be:
Invalid end-of-lines (for example, \r\n instead of \n)
Presence of the byte order mark (BOM) at the beginning of the file
Both can be fixed using vim or vi.
To fix line endings open the file in vim and from the command mode type:
:set ff=unix
To remove the BOM use:
:set nobomb
For those who don't have dos2unix installed (and don't want to install it):
Remove trailing \r character that causes this error:
sed -i 's/\r$//' filename
Details from this StackOverflow answer. This was really helpful.
https://stackoverflow.com/a/32912867/7286223

Resources