cygwin bash tab completion for arguments fork failure - bash

I have an odd problem with tab completion under cygwin's bash on my Win 7 installation. I get fork failures ('permission denied') under very specific circumstances..
Tab completion works fine for all commands.
Tab completion works fine for arguments of builtins and any cygwin-supplied program in /usr/bin, /usr/sbin, etc. (including .exe files as well as shell scripts)
Tab completion works fine for commands in my personal ~/bin directory.
However, whenever I attempt tab completion for an argument to one of my own shell scripts, I get a fork/permission denied error.
I've compared file permissions and ownerships of my shell scripts to those of cygwin-supplied shell scripts, and they are equivalent.
I've created a directory outside of the /cygwin/C hierarchy (named it /mybin) and copied my scripts into that directory. Then invoked the scripts directly (e.g., /mybin/gv n[TAB]) and the failure still occurs.
I've made sure the scripts have mode 775 and owned by me. I've made sure the directory in which the scripts exists is mode 775 and is also owned by me.
I haven't created anything in /usr/share/bash-completion (afaik, I shouldn't have to for argument-based filename completion). But I've not had issues with cygwin scripts without entries in /usr/share/bash-completion (e.g., /bin/zegrep is a shell script but has nothing under /usr/share/bash-completion)
I'm stumped at this point, but would like to resolve it since tab completion is such a vital feature.
Here's an example...
% gv n[TAB] 0 [main] bash 9308 fork: child -1 -CreateProcessW
failed for 'C:\Users\binaryb\cygwin\bin\bash.exe', errno 13 bash:
fork: Permission denied
.. in this example I was attempting to complete a filename (in current directory) by typing 'n[TAB]'. There is only one file starting with 'n' in my current directory.
I am running this under Win 7 (64 bit), with the following cygwin bash.exe version...
% uname -a
CYGWIN_NT-6.1 binaryb 2.10.0(0.325/5/3) 2018-02-02 15:16 x86_64 Cygwin
% bash --version
GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

I think I found the problem, but I'm not 100% sure. It seems to occur for scripts whose filenames are only 1 or 2 characters long. If I rename my script to, say, gvx, the problem goes away.
% gv n[TAB] 0 [main] bash 4556 fork: child -1 - CreateProcessW
failed for 'C:\Users\binaryb\cygwin\bin\bash.exe',
errno 13 bash: fork: Permission denied
% mv ~/bin/gv ~/bin/gvx
% gvx n[TAB]
% gvx newfile.txt

Related

Makefile: writing filtering outputs to separate files [duplicate]

I found a difference of behaviour between GNU Make 4.1 and 3.81 and wonder whether my code is not POSIX compliant which 4 is enforcing more strictly, or whether something else is going on.
I distilled the failure case to this Makefile
.POSIX:
all: test-b
test-a:
cat a.txt b.txt c.txt >results.txt
test-b:
cat {a,b,c}.txt >results.txt
Assuming those files have been created with cat {a,b,c}.txt, target test-a always works, yet test-b works on Make 3.81 but fails on 4.1.
The output for 3.81:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
$ make
cat {a,b,c}.txt >results.txt
$ echo $?
0
The output for 4.1:
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ make
cat {a,b,c}.txt >results.txt
cat: {a,b,c}.txt: No such file or directory
Makefile:9: recipe for target 'test-b' failed
make: *** [test-b] Error 1
$ echo $?
2
It's possible the cat command is actually failing in 3.81 and it just isn't pointing it out, as later versions of GNU Make mention passing the -e flag to the shell when invoking target commands to make it more POSIX compliant, but I can't see how that command could be failing.
I assume the wildcards are handled solely by the shell, so I can't see how invoking the shell via a make target command should be any different.
Which is these behaviours are correct? If wildcards like that don't work in Makefiles, which other wildcards can I assume to work?
test-b still fails in 4.1 even if .POSIX: is removed from the file.
Recipes are sent to the shell. They are not interpreted by make. So your question is really, are curly-brace expansions supported by the shell?
That depends on which shell make uses. They are not supported by POSIX standard sh. They are supported by bash (and many other shells).
Make always invokes /bin/sh, regardless of what shell you personally use, unless you specifically set the make SHELL variable to something else. On some systems, /bin/sh is a symlink to /bin/bash so they are the same thing (bash runs in a "POSIX emulation" mode when invoked as /bin/sh but most bash features are still available). Other systems use different shells, such as dash, as /bin/sh which do not have extra bash features.
So, you can either (a) not have a portable makefile and assume /bin/sh is the same as /bin/bash, (b) set SHELL := /bin/bash in your makefile to force it to use bash always (but fail on systems that don't have bash installed), or (c) write your makefile recipes to use only POSIX sh features so it works regardless of which shell is used for /bin/sh.

git completion broken by bash profile alias 'test'

I had an alias in my bash profile like this:
alias test='cd /Usr/work/dir/test'
every time I would try to use bash completion for git in a terminal it would:
freeze the terminal immediately after hitting tab.
take me to that directory.
As soon as I removed that alias bash completion for git works fine. Why's that?
git version 2.26.2
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.
test is a built-in command, and creating an alias named test shadows it, which could lead to unforeseen issues. Pick a different name.
alias goto_test='cd /Usr/work/dir/test'
However, this is probably the least desirable solution. First, consider using a function instead:
goto_test () {
cd /Usr/work/dir/test
}
Second, you can add /Usr/work/dir to your CDPATH variable, so that you can quickly switch to any subdirectory without having to use the entire path.
$ CDPATH=/Usr/work/dir
$ cd test
/Usr/Work/dir
$ pwd
/Usr/Work/dir/test
This saves you from having to define multiple aliases or functions if there are several directories you might commonly switch to.

BASH_VERSINFO differs from what bash --version shows

I tried copying from /usr/local/Cellar/bash/4.4.19/bin/bash to /usr/local/bin/bash because which bash shows /usr/local/bin/bash.
~/cat /etc/shells
/usr/local/Cellar/bash/4.4.19/bin/bash
~/bash --version
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.3.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
echo $BASH_VERSINFO
3
How do I fix this?
bash --version shows the version that would be run if a new shell were started from the PATH.
Thus, this version correlates with the install location from which bash (if not modified by aliases/functions/etc), or type bash (more accurately), or with the shell used to run a script with a #!/usr/bin/env bash shebang.
$BASH_VERSINFO and $BASH_VERSION show the version that's running right now.
Thus, if you're in a script with a #!/bin/bash shebang, or an interactive shell script for a user whose password database specifies /bin/bash as their shell, /usr/local/bin/bash (or any other location) being earlier in the PATH is irrelevant for purposes of the current, not-started-from-the-PATH shell instance.
To start the shell from the PATH in a script, change your shebang to #!/usr/bin/env bash. To start a specified shell from an interactive session, use chsh to update your account's settings.

Remove bash autload in terminal

My terminal tries to start cgminer when it's opened, but cgminer is not installed. How do I remove cgminer from the autoload? It's not in the bash profile file.
Error: -bash: cgminer: command not found
The bash program will execute a few profiles. You can check which ones to start with by issuing the command:
man bash
Skip to the end, and you will find the ones used on your particular operating system. On one of my computers, the list looks like:
/etc/profile
~/.bash_profile
~/.bashrc
~/.inputc
Different versions and different operating systems may have others.

How can I debug the Bourne Shell with gdb?

I built a toolchain script to prepare a Linux build environment. The script can be found here: https://github.com/mynameismevin/prometheus/blob/toolchain/ptool-make.sh
The script runs perfectly until after the Perl section around line 416. After Perl is done, when it goes to unzip sed, it complains with this error:
tar (child): sed-4.2.2.tar.bz2: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
However, if I run the sections by hand, it completes without errors. If I split the script into ptool-make1.sh (which ends at Perl) and ptool-make2.sh (which starts at sed) and run them sequentially then they both complete without any issues at all. At this point, I assert the issue isn't with the script, and I would like to debug the shell to see if it's an issue with the shell.
Here are some useful configurations:
user#ubuntu:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
user#ubuntu:~$ bash --version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
user#ubuntu:~$ ls -lh $(which bash)
-rwxr-xr-x 1 root root 998K Oct 7 2014 /bin/bash
I don't think Ubuntu bash comes with debugging symbols, so I would assume I would have to recompile to include those?
How would I use gdb to debug the shell when I run a script? Or how would I have the shell log to a file while the script runs so I can open it with gdb after it's done? I know how to debug a shell script, I don't want to debug the script, I want to debug the shell.
Edit: It doesn't look like Ubuntu bash comes with debugging symbols out of the box. Reading symbols from bash...(no debugging symbols found)...done.
Edit: $PROMETHEUS is set in my root shell. At the end of Perl cd .. results in the same results a cd $PROMETHEUS/sources/.
Shells come with their own debugging tools. The most simple is running them with -x (bash -x ...script...) which will print each command after variable expansion but before it is executed. That's usually enough to determine the problem.
For more ideas, see How to debug a bash script?
You should also consider to write helper functions to reduce the size of the script to just a few lines. You could move special options to configure or post-build steps into extra files and run them from the helper function if they exist.
Looking at the code, it seems that this line is the culrit:
cd $PROMETHEUS/sources/
everywhere else, you just use cd ... If PROMETHEUS isn't defined (the script doesn't define it, that becomes cd /sources/ which should also fail but doesn't abort your script. Try
cd $PROMETHEUS/sources/ || exit 1
instead. Also #!/bin/bash -u might be useful (abort on undefined variables).
Lastly, you can use pushd and popd to navigate the folders.

Resources