Bash script syntax error "do"? - linux

#!/bin/sh
for repo in repoA, repoB, repoC;
do
echo Cloning $repo.
done
When I execute this (sh myscript.sh) I get the following:
myscript.sh: line 2: syntax error near unexpected token `$'\r''
'yscript.sh: line 2: `for repo in repoA repoB repoC;
Ideas?

Windows uses two characters at the end of each line: '\r' and '\n'. Unix just uses '\n'. Presumably you're editing this in notepad and running it in cygwin, which is why you're getting this error.
Download the Notepad++ editor, which has an option for unix-style line endings under Edit / EOL Conversion.

You're script was probably written on a windows machine and contains DOS newlines CR LF instead of Unix ones, LF
So you just need to convert the newlines.
You can do that using a variety of tools but my preference is dos2unix
To install it on CentOS, Fedora or RHEL do:
sudo yum install dos2unix
To install dos2unix on Ubuntu or Debian:
sudo apt-get install tofrodos
sudo ln -s /usr/bin/fromdos /usr/bin/dos2unix
Now to actually do the conversion do:
dos2unix your_script.sh
Then run the script
sh your_script.sh

You forgot a semicolon:
#!/bin/sh
for repo in repoA repoB repoC;
do
echo Cloning $repo.
done
Note that repoA, repoB and repoC are being treated as variables in this context.

Related

Node script executable not working on Mac : env: node\r: No such file or directory

I have created my node script executable to execute some tasks grunt. On Windows, my node script works fine. But on Mac OS X (Yosemite), it's not working.
My node script has been published on Windows.
My node script is installed via npm command :
npm install -g task-app
My node script have this first line :
#! /usr/bin/env node
I tried many some solutions to solve my problem but I'm still stuck.
Here's these solutions that I used :
uninstall and reinstall Node.js
execute this command to
create a link for node : sudo ln -s /usr/bin/nodejs
/usr/local/bin/node
set my path with this command : export PATH=$PATH:/usr/local/bin/node
Do you have other solutions to propose ?
EDIT :
the beginning of my script :
#! /usr/bin/env node
var grunt = require('grunt');
//Get parameters from command line
var args = process.argv.splice(2);
[...]
After all, I found the solution to my problem.
As my node script file has been created on Windows, the file is DOS format (line endings in DOS format I think). So, I used a module which allow to converting a file to a unix format :
brew install dos2unix
sudo dos2unix /usr/local/lib/node_modules/task-app/src/task-app.js
You could also use vim:
vim script
:se ff=unix
:wq
That will confirm DOS-style newlines to Unix-style newlines.
There is a problem with newlines in your script. Make sure that #!/usr/bin/env node is followed by \n (unix style) instead of \r\n (windows/dos style).
To fix that, use the tr command to remove \r's from your file:
cat your_script.js | tr -d '\r' > fixed_script.js
As PauloDev says above, this is a Mac/Windows line ending issue. To elaborate, if you are using nvm you'll need to locate your script first (in my case I'm using express-mvc-generator):
# install dos2unix
brew install dos2unix
# output the full path of your node version
which node
>> /Users/<username>/.nvm/versions/node/v8.0.0/bin/node
# confirm the file path
cat /Users/<username>/.nvm/versions/node/v8.0.0/lib/node_modules/express-mvc-generator/bin/express
# convert the line endings
sudo dos2unix /Users/<username>/.nvm/versions/node/v8.0.0/lib/node_modules/express-mvc-generator/bin/express
# then run your script
Reason:
This is typically due to a difference in line endings, especially the difference in LF vs. CRLF . Unix systems like Linux and macOS use LF , the line feed character, for line breaks by default. Windows, on the other hand, is special and uses CR/LF , carriage return AND line feed character, by default.
Ref: https://qvault.io/clean-code/line-breaks-vs-code-lf-vs-crlf/
Solution:
For mac users, change CRLF to LF in that file in which the error occurred.
This should no longer be a problem since npm#^5.4.0. npm will now auto-convert to the correct line endings. See https://github.com/npm/npm/issues/12371.
This is, however, still an issue in yarn: https://github.com/yarnpkg/yarn/issues/5480.
If you've come to this page because you've encountered this error when using yarn instead of npm, like I did, you might want to consider using npm instead of yarn. npm has most of yarn's best features these days, anyway (arguably).
The carriage return inserted by MS-DOS is interpreted as part of the script interpreter name, which is the correct behavior for Un*x systems by the way. Hence, the system looks for a file /usr/bin/node\r instead of /usr/bin/node. As others have pointed out, npm now "fixes" the problem by stripping off the newline character which is a somewhat dubious behavior.
Executable files with a shebang line that has a DOS line ending are corrupt and must be fixed by the author and not by users, npm, or yarn. At the time of this writing, there is little reason to still use DOS line endings, even if you develop on Windows systems. But you should at least fix the files you produce before distributing them to the general public. See https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings for how to configure git to handle line endings correctly.
The first command tells Git to never change line endings (in the future). Next, we refresh each repository by removing every file from Git's index and, finally, rewriting the Git index to pick up all the new line endings. This fixes the CRLFs that were introduced to your local file system when you cloned each repository.
Run this command:
git config core.autocrlf false
git rm --cached -r .
git reset --hard

Any command we can use to convert windows file to unix or mac file?

I don't want to use dos2unix tool. I want to use command in Ubuntu terminal to convert Windows file to Unix file. Is that possible. I have looked through other articles and tried those commands but none working. Anyone can help?
You can use tr to remove carriage returns like this:
tr -d '\r' < WindowsFile > UnixFile
You can use
cat -vet WindowsFile
to see if there are carriage returns in your file and they'll show up as ^M
I want to use command in Ubuntu terminal to convert Windows file to Unix file.
dos2unix path/to/file/to/convert
I don't want to use dos2unix tool.
alias notdos2unix=dos2unix
notdos2unix path/to/file/to/convert
For Ubuntu(and Debian) you can use the tofrodos package.
sudo aptitude install tofrodos
fromdos file.txt # converts the file to UNIX line-endings
todos file.txt # converts the file to Windows line-endings
OSX (being a derivative of UNIX) should have the same line-endings as UNIX.
If you're on Windows, you can find tofrodos binaries here.
If you're on a Mac, you can use the brew package manager and install the tofrodos on OSX.

Jenkins: special characters getting inserted in bash script

I am executing a bash script inside. A command like this when executed
current_loc=/tmp/$BUILDTYPE
rm -rf $current_loc/*
[ -d $current_loc/ ] || mkdir -p $current_loc
Get replaced by
+ current_loc=$'/tmp/stage\r'
+ rm -rf '/tmp/stage
/*
'
+ '[' -d $'/tmp/stage\r/' ']'
+ mkdir -p $'/tmp/stage\r\r'
The dollar quoting and \r is creating havoc. How do I fix this?
You must replace '\r' symbol with command like
BULDTYPE=$(echo $BULDTYPE | tr -d '\r');
There are several ways to run a BASH script in Jenkins. Way #1 is to create a bash script and have Jenkins execute it as part of the build process. However, you can also type in a BASH script directly into Jenkins. Which way are you doing this?
My suspicion is that you've written your shell script using Notepad on Windows and then are executing it on Unix or on a Cygwin installation which is set to take Unix line endings. The \r you're seeing are there in your shell script itself.
You can reedit the script using a program editor, and then setting the line endings to Unix line endings. In VIM, you can do this by:
:set ff=unix
in the Command Mode.
If you use Notepad++ on Windows (free download and open source), you select the Edit->EOL Conversion->Unix menu item. (Or you can use Vim)
You can run the dos2unix utility that most Unixes and Linux installations have, but I'd look over the script anyway in a program editor.
Do not use a non-program editor to edit a program. I've seen people use Winpad and forget to save the script as Text. Instead, they create a shell script in RTF format. RTF format makes Unix BASH shell sad.

simple linux script

I'm having problems creating an automated script to isntall solr on a new server
sudo cp "apache-solr-3.3.0/dist/apache-solr-3.3.0.war" "/var/lib/tomcat6/webapps/solr.war"
sudo cp -R "apache-solr-3.3.0/example/solr/" "/var/lib/tomcat6/solr/"
sudo cp "solr.xml" "/etc/tomcat6/Catalina/localhost/solr.xml"
rm -R "apache-solr-3.3.0"
sudo service tomcat6 restart
I get
cp: target `\r' is not a directory
cp: target `\r' is not a directory
rm: cannot remove `\r': No such file or directory
* Usage: /etc/init.d/tomcat6 {start|stop|restart|try-restart|force-reload|status}
It seems because I use line breaks to terminate the commands (as if it were a windows bat file). How do I run multiple commands in a single file
You are probably using Windows line breaks in your script. Convert them to Linux line breaks with the dos2unix utility: dos2unix your_script.sh
The issue appears to be that your shell script has windows line endings (\r\n). Bash only cares about the \n and so the \r is interpreted as being a part of the command.
You need to change the line endings to unix (\n only). dos2unix can do this for you.
Correct the line endings in your script to use the unix standard \n. Unfortunately you have \rs there as well and it looks like the shell passes them as last arguments.

Bash script: bad interpreter

Question: I get this error message:
export: bad interpreter: No such file or directory
when I execute this bash script:
#!/bin/bash
MONO_PREFIX=/opt/mono-2.6
GNOME_PREFIX=/opt/gnome-2.6
export DYLD_LIBRARY_PATH=$MONO_PREFIX/lib:$DYLD_LIBRARY_PATH
export LD_LIBRARY_PATH=$MONO_PREFIX/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=$MONO_PREFIX/include:$GNOME_PREFIX/include
export ACLOCAL_PATH=$MONO_PREFIX/share/aclocal
export PKG_CONFIG_PATH=$MONO_PREFIX/lib/pkgconfig:$GNOME_PREFIX/lib/pkgconfig
PATH=$MONO_PREFIX/bin:$PATH
PS1="[mono-2.6] \w # "
But the bash path seems to be correct:
asshat#IS1300:~/sources/mono-2.6# which bash
/bin/bash
asshat#IS1300:~# cd sources/
asshat#IS1300:~/sources# cd mono-2.6/
asshat#IS1300:~/sources/mono-2.6# ./mono-2.6-environment
export: bad interpreter: No such file or directory
asshat#IS1300:~/sources/mono-2.6# ls
download mono-2.4 mono-2.4-environment mono-2.6 mono-2.6-environment
asshat#IS1300:~/sources/mono-2.6# cp mono-2.6-environment mono-2.6-environment.sh
asshat#IS1300:~/sources/mono-2.6# ./mono-2.6-environment.sh
export: bad interpreter: No such file or directory
asshat#IS1300:~/sources/mono-2.6# ls
download mono-2.4-environment mono-2.6-environment
mono-2.4 mono-2.6 mono-2.6-environment.sh
asshat#IS1300:~/sources/mono-2.6# bash mono-2.6-environment
asshat#IS1300:~/sources/mono-2.6#
What am I doing wrong? Or is this a Lucid Lynx bug?
I did chmod + x
The first line, #!/bin/bash, tells Linux where to find the interpreter. The script should also be executable with chmod +x script.sh, which it appears you did.
It is highly likely that you created this file with a windows editor, which will place a <cr><lf> at the end of each line. This is the standard under dos / windows. OS X will place a <cr> at the end of each line. However, under Unix / Linux, the standard is to just put a <lf> at the end of the line.
Linux is now looking for a file called /bin/bash<cr> to interpret the file,
where <cr> is a carriage return character, which is a valid file character under Linux. Such a file doesn't exist. Hence the error.
Solution: Edit the file with an editor on Linux and get rid of the extra <cr>. One tool that usually works when the file is edited on Windows is dos2unix.
Could the script be using Dos newlines?
Try running dos2unix on it.
It looks like things have been configured to override the export builtin somehow. This can be done via an exported function or the enable builtin, for example. Try putting type export in the script to check. If you are setting BASH_ENV, you probably shouldn't.
If bash is called as sh, it enables POSIX mode and does not allow export to be overridden with a function, as required by POSIX. Likewise, most other shells installed as /bin/sh follow POSIX in this and/or do not allow the execution environment of a script to be messed up so strongly as through importing functions from the environment.
By the way, the script seems designed to be sourced, i.e. . ./mono-2.6-environment instead of ./mono-2.6-environment.
Had the same problem. Used brute force:
/bin/sh /full/path/to/configure --options
& this did the trick
(Of course I'd like to know why)
I encountered a similar error but in my case I forgot to add / before bin and I was encountering the bad interpreter error. Also tried to do
sudo apt-get install dos2unix -y package.
I was using this originally :
#! bin/bash ( i was missing / before bin )
Double check the path as well.
This could be a case of a shebang with homoglyphic unicode characters. In other words, you may have invisible or look-alike characters in the shebang which don't actually represent the string #!/bin/bash. Try looking at the characters in a hex editor.
what worked for me was when dos2Unix wasn't on the system I was working with:
sed -i s/{ctrl+v}{ctrl+m}// filename
This happens sometimes when file system goes funny.
Try to move or rename the file.
If you see "Stale file handle" error this is your problem.
e.g. happened us with CentOS docker
$ ./test.sh
-bash: ./test.sh: /bin/bash: bad interpreter: Invalid argument
$ ls -alstr test.sh
20 -r-xr-xr-x 0 omen omen 17874 Jun 20 01:36 test.sh
$ cp test.sh testcopy.sh
$ ./testcopy.sh
Happy Days
$ mv test.sh footest.sh
mv: cannot move ‘test.sh’ to ‘footest.sh’: Stale file handle
$ rm test.sh
rm: cannot remove ‘test.sh’: Stale file handle
You can copy the file and read it.
But not move it!
Nor remove it.
Some weird docker file-system thing maybe.
Solution: re-create the docker container OR maybe file system repair disk would help
OR of course format c: :-D :-o

Resources