I'm trying to compile a program (sbcl to be precise) under Wine + MinGW/Cygwin environment. I've fixed plethora of different quirks, but now I'm stuck on the fact that this environment breaks command line arguments in weird way. The problem is that build shellscript contains the lines
./src/runtime/sbcl --core output/cold-sbcl.core \
--lose-on-corruption $SBCL_MAKE_TARGET_2_OPTIONS --no-sysinit --no-userinit \
--eval '(sb-fasl::!warm-load "src/cold/warm.lisp")' --quit
...but within the running sbcl process the last command line argument appears as (sb-fasl;!warm-load "src/cold/warm.lisp"), which is, of course, syntactically incorrect and the build fails.
I've performed some tests with different versions of wine (I've tried versions 6.0, 6.12 and 6.15) and win32 bash (I've tried a plenty of those, including busybox for windows, currently stuck with the one from old MSYS-20111123.zip from here since it does not exhibit FAST_CWD bug that is currently not fixed). It appears that every time the command line contains both double colon and forward slash, some part of the environment changes double colon to semicolon. I'm not sure where to look for that behaviour to circumvent it - is that shell escaping, or exec syscall behaviour? Could it be that this behaviour is hardcoded into exec function in msvcrt.dll?
Related
I'm having an issue with WSL2:
$ where b4a
/usr/local/bin/b4a
$ b4a new
/usr/local/bin/b4a: 1: Not: not found
Even though where finds commands, I can't run them. And it's not a PATH issue either:
echo $PATH
/usr/local/sbin:/usr/local/bin:[...]
And b4a isn't the only command with this problem. What could be the cause? My distribution is Debian 10 and host is Windows 10.
Not necessarily a full answer, but hopefully the troubleshooting methods you need to arrive at a solution ...
Note that it doesn't say that the command itself isn't found. For instance, if you run:
# lllllllllll
lllllllllll: command not found
That's truly a command not found. This is different. While I don't (yet) know the exact cause, this seems closer to the issues we might see with improperly quoted paths with spaces in a shell script.
You mention that other commands have this problem -- Is there something in common with the commands that don't work properly? Is it possible that they are all shell scripts?
Try several things to debug:
Start WSL without your startup profile. It's very likely that something (or you) added a line that is causing problems. From PowerShell or CMD:
wsl ~ -e bash --noprofile --norc
b4a
If that works, then there's a problem in one of your startup files that you'll need to debug. Look for anything modifying environment variables without proper quoting, especially the PATH. WSL automatically appends the Windows path to your Linux path to make it easy to run Windows commands, but the fact that almost every Windows path has spaces in it can cause problems for unsuspecting scripters that don't take this corner case into account.
Having a space in a path is fully allowed in Linux, but some scripts just don't handle it properly.
If the command that is failing is a shell script, trying starting it with:
bash -x /usr/local/bin/b4a
Or even start WSL with wsl ~ -e bash -x to see all trace output from the shell.
In this case, you'll be looking for some problem in the script right around where it actually fails.
If all else fails, you can disable WSL's PATH modification via its config file:
sudo -e /etc/wsl.conf
Add the following:
[interop]
appendWindowsPath = false
Then exit Debian, run wsl --shutdown and restart Debian. Try the b4a command again.
If this works, then the problem is almost certainly due to some problem in the PATH quoting in these commands. I don't recommend it as a permanent solution since you will have to type out the full path of Windows applications each time you want to run them.
I have npm and node installed (tried NVM for Windows and direct installations).
When running 'npm -v' or 'node -v' in Git Bash everythings works fine. But when I try to run 'npm run dev' (or any other command) the output says that 'node command is not recognized'.
In other shells (CMD/Powershell) everything works fine.
I've checked Path variable in Windows, Path variable in Git Bash, everything seems to be correct.
Error screenshot
Path variable screenshot
Path variables cmd/procmon
Any help appreciated.
p.s. While I was trying to find an answer I saw the same question from #jameseg , maybe if he sees this one he could help.
Your PATH environment variable is quite a mess. It has duplicate entries, also has an entry C:\Program Files\nodejs\node.exe which is not valid because it should be a folder, not a file, and it has . in the middle which doesn't make much sense either.
But the main problem is that it has a stray doublequote, after C:\Program Files\Java\jdk-13.0.1\bin:
With this, effectively all the paths after it are ignored, because they are treated as part of one big quoted string (which is implicitly terminated by the end of the variable data).
To illustrate what I mean, consider this example:
This correct PATH variable...
C:\a;C:\b;"C:\c 123";C:\d;C:\e
...is interpreted as:
C:\a
C:\b
C:\c 123
C:\d
C:\e
But, this bad PATH variable where I deleted one of the quotes...
C:\a;C:\b;C:\c 123";C:\d;C:\e
...is interpreted like this:
C:\a
C:\b
C:\c 123";C:\d;C:\e
This may at first make only half sense, but it's because of the quirky way Windows parses this variable: When encountering a doublequote, it's removed from the result but toggles a flag that says whether we are now inside a quoted string. And when the flag is set, semicolons are ignored. So even if the stray quote is at the end of a path (or in the middle of it), it will have the effect of essentially quoting the rest of the variable data until the next doublequote or the end of the data.
Confusingly, you may still have where node report that it found node, because the where.exe tool does its own parsing, in a slightly different way (ignoring quotes), so you cannot rely on its output! (For example, try set PATH=c:\win""dows. where explorer will say it can't be found, yet explorer will work to open Explorer. You get the opposite with something like set PATH=x"y;c:\windows - where explorer will list c:\windows\explorer.exe, yet explorer will not work.) The reason why it works in Git Bash is probably the same: when the environment variables are translated to UNIX paths, they are parsed slightly differently than Windows would do it itself, inadvertently correcting the problematic entry in the process.
So, the solution is to remove this doublequote from your path variable.
I've been writing a Tkinter program and I don't want the console to show, so I used a .pyw file. However the program ran with an error that said the program could run usr/bin/python3, so I removed the shebang line, and it worked, but do I need a shebang line? Or should I keep it as is.
If it works without the shebang line:
Your computer found a version of Python to run it (likely in your "PATH" environment variables).
If it didn't work with the shebang line, either:
You made a typo, or
You gave it an incorrect path to your version of Python
Make sure you know exactly where Python is installed on your device:
Mac/Linux
Windows
(To anyone simply copy-pasting what you see in tutorials - without a good grasp of what it's doing: Try googling terms like "shebang line" and figure out what they might be doing behind the scenes)
Well the idea goes as followed,
I have a bash file for linux, there I obviously run it by making ./my_run.
The problem is I'm in windows so I downloaded and installed cygwin.
I added cygwin bin to the Enviromental Variables and check that at least "ls" works so I guessed I did it well.
When I try to run it with the cmd it displays:
'.' is not recognized as an internal or external command,
operable program or batch file.
As if the cygwin variables were not correctly installed (as I said I tried ls and works).
Then I tried it directly with cygwin and when doing the ./my_run I got it to work right.
So how is that I can use some commands like ls but when doing ./ it doesn't work on the cmd? How can I fix this?
Well, cygwin is only a shared library and a lot of stuff (the programs) using it (read Cygwin doc). cygwin.dll changes internally path resolution / chars to allow you to say ./my_script and converts it to .\my_script before doing the actual windows call, it also adds the proper extension to executables to allow it to execute windows binaries. This magic persists as long as you use it. cmd.exe is a Microsoft Windows command shell that is completely unaware of Cygwin's shared library and by that reason it doesn't use it, so it will not call it for path translation, even if you populate the environment of zetabytes of stuff. When you run in Cygwin terminal, you are running bash shell, which is a Cygwin executable, linked to cygwin.dll. It manages to use Cygwin library for all the unix system call emulations, so when you pass it e.g. to exec("./my_script", ...);, it internally converts that to try for ./my_script, then .\my_script, ./my_script.exe, ... and the same for .com and .bat extensions.
This fact often makes some people to say that Cygwin is not a good, efficient, environment. But the purpose was not to be efficient (and it is, as it caches entries and makes things best to be efficient) but to be compatible.
In your example ls is a Cygwin executable that mimics the /bin/ls executable from unix systems. It uses the Cygwin library, so all path resolution will be properly made (well, under some constraints, as you'll see after some testing) and everything will work fine. But you cannot pretend all your Windows applications to suddenly transform themselves and begin working as if they where in a different environment. This requires some try and error approach that you have to try yourself. And read Cygwin documentation, it is very good and covers everything I've said here.
If you open up Cygwin and run the command there you should be fine.
I have an escript file which runs fine from the command line, i.e.:
./escript_file
It is meant to be cron friendly and all paths are explicit but when I run it, it fails to compile saying that there are bad attributes.
The bad attributes in question are macro definitions:
-define(COOKIE, 'somecookie').
The Answer
Thanks to Geoff Ready's suggestion I investigated which version of Erlang was running by printing out init:script_id() which prints out a string like {"OPT APN 181 O1", "R13B"} and, sure enough the command line and cron versions were picking up different versions.
The script had an initial line:
#!/usr/bin/env escript
and the operating system was 'finding' Erlang for me. The different environment variables of cron meant that a different erlang was being picked up (Geoff's first answer, and one I kinda knew but couldn't see how it would affect things).
The solution is then to force the version with a starting line of:
#!/usr/local/lib/erlang/erts-5.7.3/bin/escript
Postscript
There was also a different Ubuntu apt-get install of an earlier version of Erlang (in a different location to the source install) and an errant 64-bit install...
The cron environment just kept falling back to older and more obscure installs, failing all the while :(
Perhaps cron is picking up a different version of erlang in the path. Erlang R12B documentation says that escript ignores preprocessor directives besides include_lib. Erlang R13B documentation says that the preprocessor is run on the file. That would definitely explain the difference in behavior.
If it is working fine from the command line, a likely cause is a difference in environment variables for your interactive shell versus when cron runs the script.
Changing #!/usr/bin/env escript to #!/usr/local/bin/escript at the top of the file will work if the Erlang versions are the same.