Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better error for windows line endings in the shebang #2783

Closed
brenogil opened this issue Mar 1, 2016 · 28 comments
Closed

Better error for windows line endings in the shebang #2783

brenogil opened this issue Mar 1, 2016 · 28 comments

Comments

@brenogil
Copy link

brenogil commented Mar 1, 2016

I have recently switched to fish and I have been trying to run some .sh scripts.
Usually I have no problem but for one particular script I get the error below.

Observed behavior:

Failed to execute process './alt_script.sh'. Reason:
', which is not an executable command.he interpreter '/bin/sh

I believe at least the message could be improved, if nothing else.

Other comments:

I have tried playing with different shebangs:

!/bin/sh

!/bin/bash

!/usr/local/bin/fish


Fish version: fish, version 2.2.0

Operating system: OSX 10.10.5 - Homebrew

@faho
Copy link
Member

faho commented Mar 1, 2016

Could you upload the script?

', which is not an executable command.he interpreter '/bin/sh

I do believe you've made a copy-paste mistake here - for me the error is

The file 'FILENAME' specified the interpreter 'INTERPRETER', which is not an executable command.

Also, check that the mentioned interpreter actually exists and is executable (test -x $INTERPRETER).

And what is your locale (echo $LANG, dunno if OSX has a locale command)?

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

I do believe you've made a copy-paste mistake here

screen shot 2016-03-01 at 17 17 43

Also, check that the mentioned interpreter actually exists and is executable (test -x $INTERPRETER).

Returns nothing. Could this be the problem?

And what is your locale (echo $LANG, dunno if OSX has a locale command)?

locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"

@faho
Copy link
Member

faho commented Mar 1, 2016

Returns nothing. Could this be the problem?

It should set $status to 1 if it doesn't - your prompt displays a red cross then if I'm not mistaken.

LC_ALL="en_US.UTF-8"

You usually do not want to set LC_ALL, as it overrides all other locale variables.

Otherwise, I got nothing. No clue - anyone else? @fish-shell/contributors?

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

You usually do not want to set LC_ALL, as it overrides all other locale variables.

Ok. I undid it.

It should set $status to 1 if it doesn't - your prompt displays a red cross then if I'm not mistaken.

... I'm not sure I fully understand this. Are there any resources about it around?

@faho
Copy link
Member

faho commented Mar 1, 2016

http://fishshell.com/docs/current/index.html#variables (a bit down, under "The status variable"):

Whenever a process exits, an exit status is returned to the program that started it (usually the shell). This exit status is an integer number, which tells the calling application how the execution of the command went. In general, a zero exit status means that the command executed without problem, but a non-zero exit status means there was some form of problem. Fish stores the exit status of the last process in the last job to exit in the status variable.

and

http://fishshell.com/docs/current/tutorial.html#tut_exit_status.

Basically, test returns a status. When the test fails (i.e. the file isn't executable - which it also can't be if it doesn't exist) it will return 1. Your prompt acts on it if the last command returned something > 0 and displays a red cross, like you can see in your screenshot, so you can just execute a test and see if it failed.

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

Thanks!
test -x alt_script.sh
test alt_script.sh
test -x $INTERPRETER

all return $status 0

@faho
Copy link
Member

faho commented Mar 1, 2016

test alt_script.sh

That's not how test works. It has a few operators, but if you're not handing it any, it will check if the arguments are not empty (in a pure text sense), so it goes "Oh, I've received the text 'alt_script.sh' - that's text, so let's return 0!". See http://fishshell.com/docs/current/commands.html#test for more information.

test -x $INTERPRETER

By "$INTERPRETER", I meant the full path to the interpreter you're using in the shebang, e.g. test -x /bin/bash (that test returns 0 in this case is #2037, an instance of POSIX, the standard we follow for it, being stupid).

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

stupid me!

test -x /bin/bash
test -x /bin/sh

all return 0.

As I said, I have been able to run similar scripts.
I find the error message strange more than anything

@faho
Copy link
Member

faho commented Mar 1, 2016

As I said, I have been able to run similar scripts.

Which is why the question is: What's different about this one? Can you upload it?

@faho
Copy link
Member

faho commented Mar 1, 2016

Did this script ever have contact with a windows system? Does it work if you copy it by hand (i.e. not copy-and-pasting, but entering the text anew in a new file)?

@faho
Copy link
Member

faho commented Mar 1, 2016

I can reproduce the weird error message with the following script:

printf '%s\r' \#!/bin/bash 'echo banana' > why.sh
chmod +x why.sh
./why.sh

You might notice that printf here has a "\r" instead of the more usual "\n". That's what windows usually uses for line endings, and it's been a pain for the last two decades.

To fix your script, run sed 's/\r/\n' -i /path/to/script or dos2unix or something like that.

It's possible we could detect that and print a better error message.

@faho
Copy link
Member

faho commented Mar 1, 2016

Or, since you use emacs, open it with that and do M-x set-buffer-file-coding-system utf-8-unix, then save.

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

Did this script ever have contact with a windows system?

Yes! It is a script I tried to convert from a .bat

Or, since you use emacs, open it with that and do M-x set-buffer-file-coding-system utf-8-unix, then save.

This worked in the sense that error message does not appear anymore. :)
./alt_script.sh: line 20: wine: command not found
./alt_script.sh: line 24: wine: command not found
./alt_script.sh: line 29: wine: command not found
./alt_script.sh: line 34: wine: command not found

Does it work if you copy it by hand (i.e. not copy-and-pasting, but entering the text anew in a new file)?

Yes

@faho
Copy link
Member

faho commented Mar 1, 2016

./alt_script.sh: line 20: wine: command not found

Let me go out on a limb here - my guess is, and this is purely a guess, that you either don't have wine installed or don't have it installed in $PATH (command -s wine doesn't work).

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

I don't think its is the case. I've been relying heavily on wine. (that sounds bad)
./alt_script.sh: line 52: mkdir: command not found
./alt_script.sh: line 64: rm: command not found
./alt_script.sh: line 66: `done'

I guess I'll have to figure it out what is going on...

@faho
Copy link
Member

faho commented Mar 1, 2016

If you want, you can upload the script and I'll have a look. That it doesn't find mkdir or rm sounds like you misconfigured $PATH (your config.fish would be nice as well, my guess is you have something like set PATH /usr/local/bin:$PATH in there when it should be set PATH /usr/local/bin $PATH - note the colon). That it doesn't find done is to be expected, just like it wouldn't find fi or esac - all those are end in fish. Sorry, it's an sh script, I forgot.

@faho faho added the question label Mar 1, 2016
@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

This is the file.

It is a direct copy from this one

@faho
Copy link
Member

faho commented Mar 1, 2016

The last done is wrong, because you've not started a for/while loop - just remove it.

Otherwise it looks okay.

Add echo $PATH to the top to check what sh thinks your path is, and then confirm that rm and mkdir exist in one of those directories.

@brenogil
Copy link
Author

brenogil commented Mar 1, 2016

Thanks!
I'd say most of it was outside of the actual fish scope, but I'd be glad if at least this effort improves that error message a bit.
:)

@faho
Copy link
Member

faho commented Mar 1, 2016

Okay then. If you have any other questions, feel free to ask!

@faho faho closed this as completed Mar 1, 2016
@Optiligence
Copy link

in summary: the problem is windows line endings in the script

PS/my 2 cents: i think it’s odd that this just breaks

@endolith
Copy link

endolith commented Oct 4, 2019

It should just handle all line endings correctly. It produces weird error messages:

image

@faho
Copy link
Member

faho commented Oct 4, 2019

@endolith Tell that to the kernel folks, which is where the error comes from. Fish has nothing to do with this and can't do anything about it.

@zanchey
Copy link
Member

zanchey commented Nov 1, 2019

The error message is super weird though! At least if it was "The file './build.sh' specified the interpreter '/usr/bin/fish\r', which is not an executable command.", people would have some hope of working it out.

@lilyball
Copy link
Contributor

lilyball commented Nov 1, 2019

It's super weird because of the raw control character in there (the carriage return). The kernel isn't doing any escaping of control characters in its output.

@zanchey
Copy link
Member

zanchey commented Nov 1, 2019

Right. Unfortunately doing that escaping safely in postfork is a bit irritating; I have a hacky patch but it's probably not the right approach.

@zanchey
Copy link
Member

zanchey commented Nov 3, 2019

Reopening this to track the improvement.

@zanchey zanchey reopened this Nov 3, 2019
@zanchey zanchey added this to the fish-future milestone Nov 3, 2019
@faho faho closed this as completed in 0d0ee47 Sep 25, 2020
@faho
Copy link
Member

faho commented Sep 25, 2020

Okay, I added a change that detects windows line endings in the shebang and complains about them.

That should fix, by my estimate, 99.7% of the problem.

@faho faho modified the milestones: fish-future, fish 3.2.0 Sep 25, 2020
@faho faho changed the title Error when trying execute a shell script Better error for windows line endings in the shebang Sep 25, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants