0

I am trying to run the following shell script but I am getting the "/bin/bash^M: bad interpreter" error.

Script:

#!/bin/bash
rm -rf tomcat8/webapps/cpproject*

I know that this is happening because I am editing the file on windows and trying to run it on Unix. I tried all the ways of fixing it as suggested on stackoverflow. I tried the following.

  1. Installed Vim editor and saved it
  2. In Notepad++ changed the End Of Line option to Unix. Tried to save the new documents as Unix format
  3. Installed gedit and saved it.
  4. Installed doc2unix and tried it.

I tried a lot other ways but nothing worked. Can some one suggest me how to fix this issue?

Updated:

"xxd before_install1.sh | head" command is showing the followng.

00000000: 2321 2f62 696e 2f62 6173 680a 726d 202d  #!/bin/bash.rm -
00000010: 7266 2074 6f6d 6361 7438 2f77 6562 6170  rf tomcat8/webap
00000020: 7073 2f63 7070 726f 6a65 6374 2a         ps/cpproject*

Update: I made sure that I am not running the old file. Because I changed the file name each time and tried it. I made sure that the new file is being executed each time. Basically I am using codedeploy jenkins plugin which generates the war file and zips it with scripts and appspec.yml file. Since I change the file name each time and update the appspec.yml file with new name, I am making sure that the new file is being uploaded. But it is giving the same error. Even after it is uploaded to the S3 bucket I downloaded and the zip file and made sure that it contains the latest one and even executed the xxd command and got the following.

$ xxd before_install5.sh | head
00000000: 2321 2f62 696e 2f62 6173 680d 0a72 6d20  #!/bin/bash..rm
00000010: 2d72 6620 746f 6d63 6174 382f 7765 6261  -rf tomcat8/weba
00000020: 7070 732f 6370 7072 6f6a 6563 742a 0d0a  pps/cpproject*..

Update:

@Charles Duffy, Thank you for your response. I am developing these scripts locally and pushing them to GitHub. I have a Jenkins job, which takes this code from GitHub repository and packages this into a war file. I am using "CodeDeploy" plugin, which will take this war file and zips it with these shell scripts under scripts folder and appspec.yml file and push it to S3 bucket in AWS. The following is what is happening.

xxd command in my local system file:

$ xxd before_install5.sh | head
00000000: 2321 2f62 696e 2f62 6173 680a 726d 202d  #!/bin/bash.rm -
00000010: 7266 2074 6f6d 6361 7438 2f77 6562 6170  rf tomcat8/webap
00000020: 7073 2f63 7070 726f 6a65 6374 2a0a       ps/cpproject*.

xxd command on the file after it is uploaded to GitHub:

$ xxd before_install5.sh | head
00000000: 2321 2f62 696e 2f62 6173 680a 726d 202d  #!/bin/bash.rm -
00000010: 7266 2074 6f6d 6361 7438 2f77 6562 6170  rf tomcat8/webap
00000020: 7073 2f63 7070 726f 6a65 6374 2a0a       ps/cpproject*.

xxd command on the file after it is pulled by Jenkins from GitHub to Local Workspace(in .jenkins/worspace folder)

$ xxd before_install5.sh | head
00000000: 2321 2f62 696e 2f62 6173 680d 0a72 6d20  #!/bin/bash..rm
00000010: 2d72 6620 746f 6d63 6174 382f 7765 6261  -rf tomcat8/weba
00000020: 7070 732f 6370 7072 6f6a 6563 742a 0d0a  pps/cpproject*..

xxd command on the file after it is pushed to s3 bucket in AWS:

$ xxd before_install5.sh | head
00000000: 2321 2f62 696e 2f62 6173 680d 0a72 6d20  #!/bin/bash..rm
00000010: 2d72 6620 746f 6d63 6174 382f 7765 6261  -rf tomcat8/weba
00000020: 7070 732f 6370 7072 6f6a 6563 742a 0d0a  pps/cpproject*..

I am seeing that the extra characters '0d0a' are added after the code is taken by Jenkins into Local Workspace. It's not a problem with CodeDeploy plugin at this momement, it seems. Is there any way we can avoid this?

Thank you.

Subbu
  • 217
  • 2
  • 11
  • You can use `tr -d '\015'` to delete the carriage return. – William Pursell Nov 26 '21 at 22:36
  • `sed -i 's/\r$//' file` is another way to do it, using GNU sed. – glenn jackman Nov 26 '21 at 22:45
  • Tried both of the above but didn't work. – Subbu Nov 26 '21 at 22:51
  • There is definitely not a `^M` (aka a CR, aka a `$'\r'`) in the file you show the `xxd` dump of in the question. Which is to say, you've successfully removed the faulty character -- are you sure you're _running_ that corrected file, not the original one with the DOS-style newlines? – Charles Duffy Nov 26 '21 at 23:37
  • BTW, note that UNIX text files have newline **terminators**, not just newline **separators**. Every valid line of text should have a newline after it, _including_ the last one in the file. (This is the other thing that's different between DOS and UNIX text file formats). – Charles Duffy Nov 26 '21 at 23:42
  • 1
    you mean doc2unix or dos2unix? – ufopilot Nov 27 '21 at 00:17
  • `before_install5.sh` has `0d0a` -- aka `\r\n` -- aka CRLF -- aka, it has the problem that `dos2unix` fixes. Compare to your `before_install1.sh` which only has `0a`s (`LF`s) for its newlines, and is thus correct. – Charles Duffy Nov 27 '21 at 17:56
  • BTW, where are these files coming from? If they're being checked out from a source control system, many revision control systems can be configured as to whether and what kind of newline conversion they do based on which operating system code is being checked out on. So if you're trying to, say, run the file through dos2unix and then check it into git after the change, that may not make any difference, if git itself is configured to convert it to have CRLFs. – Charles Duffy Nov 27 '21 at 17:59
  • @CharlesDuffy, updated the question with more details. Can you please check it? – Subbu Nov 27 '21 at 18:39
  • Reopening this since you added enough details to distinguish it from the previously linked duplicate. Could you add details on _how_ the push to S3 is done? If it's done with this "CodeDeploy" plugin, details on how that plugin is configured might be a place to start. (Also, you might think about _not_ using it, if it's messing up your files). – Charles Duffy Nov 27 '21 at 18:54
  • Another place to start might be to add some logging in the tools/scripts that call CodeDeploy, to check the files _as they exist in the environment where those scripts run_ immediately before the upload. Just because things look one way in a development environment doesn't necessarily mean they'll exist that way in a production environment, unfortunately. – Charles Duffy Nov 27 '21 at 18:59
  • (details on how the "after it is uploaded to github" snapshot was taken, in particular, are pertinent; if the path didn't go through the same copy of git that does the checkout pre-deployment, the results may differ depending on configuration). – Charles Duffy Nov 27 '21 at 19:00
  • ...see f/e the setting `core.autocrlf` documented in https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration -- if that's different between your personal system and the CI environment, your results will differ likewise. – Charles Duffy Nov 27 '21 at 19:02
  • 1
    @CharlesDuffy, Sorry! I just did one more check. I verified the file after it is pulled by Jenkins into local workspace and that's where it is adding the DOS line. It's not the problem with CodeDeploy push to S3. So, updated the question heading and description also. Sorry about the confusion. – Subbu Nov 27 '21 at 19:23
  • The _easy_ answer here, albeit maybe not the _best_ one, is to have Jenkins run `dos2unix` after the file is already in your workspace. – Charles Duffy Nov 27 '21 at 19:45
  • Relevant, btw: [For the Jenkins git plugin, where is it recommended to run `git config`?](https://stackoverflow.com/questions/34768593/for-the-jenkins-git-plugin-where-is-it-recommended-to-run-git-config) – Charles Duffy Nov 27 '21 at 19:45
  • @CharlesDuffy, looks like dos2unix is working. Have to add the sh executable to jenkins and use the command. But GitHub is down now and will post the solution if it works. Thank you. – Subbu Nov 27 '21 at 21:14

2 Answers2

1

If the script is called 'myscript.dos', you can delete the carriage returns with tr:

tr -d '\015' < myscript.dos > myscript.unix
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Tried the above but didn't work – Subbu Nov 26 '21 at 22:51
  • What do you mean by "didn't work"? Do you mean that `myscript.unix` contains carriage returns, or do you mean that you still cannot executre `myscript.dos`? – William Pursell Nov 26 '21 at 22:52
  • My script is saved as before_install.sh. So I executed the command "tr -d '\015' before_install1.sh" and it saved the file before_install1.sh. But when I run the before_install1.sh script on linux machine and I am getting the same error again. – Subbu Nov 26 '21 at 22:54
  • 1
    What does `xxd before_install1.sh | head` show? – William Pursell Nov 26 '21 at 23:00
  • Updated the questions with "$ xxd before_install1.sh | head" results. Please check. – Subbu Nov 26 '21 at 23:08
  • 1
    Your `before_install1.sh` indeed does not have the problem that `tr` was intended to resolve -- presumably meaning the problem _was in fact_ fixed, but you're running the old file that didn't have the fix. – Charles Duffy Nov 26 '21 at 23:36
  • @Charles Duffy, I made sure that I am not running on the old file. Updated the question with details. Please check. – Subbu Nov 27 '21 at 17:54
  • @Subbu, I've commented on the question. – Charles Duffy Nov 27 '21 at 17:57
1

@Charles Duffy, Thank you for your time and patience in resolving this issue. It is finally working. I am just posting the actual problem and solution here so that it will be useful for other.

Work: I am working on developing a deployment strategy into AWS using Jenkins and AWS CodeDeploy. I am using CodeDeploy plugin in Jenkins. Jenkins will create a war file and CodeDeploy plugin will create a zip file with the war file, appspec.yml and some shell scripts to stop, start servers etc and this zip file will be pushed to S3 and from there CodeDeploy will be triggered and deploy the war file.

Problem: The shell scripts used to start the server or stop the server are developed in windows system. So it is adding DOS lines to the scripts so they are not running on Unix in EC2 machines. I have removed the DOS lines on the shell scripts by using different techniques. But since Jenkins is running locally (On Windows Machine), when the code is pulled from GutHub it is again adding DOS lines.

Solution: Please check the above questions and the solutions given by all to find out how to identify if DOS line are being added to shell scripts. Since, in my case, the DOS lines are added by Jenkins I have to clear them in Jenkins before it is going to produce a zip file.

Go to Jenkins and configure the shell executable first. Since I have git installed on my system, I have a Shell executable in my system.

enter image description here

Once this is done, go to the Jenkins job created and add "Execute Shell" build step and add the commands shown in the below picture.

enter image description here

This will remove all the DOS lines added to the scripts and your shell scripts will be executed correctly by codedeploy in AWS on Linux system.

Thank you @Charles Duffy and others who helped me in resolving these issues.

Thank you very much, Subbu.

Subbu
  • 217
  • 2
  • 11