Shell builtin - bind - bash

Edit:
This was due to my PS1 Variable being jacked up (refer to answer section for solution).
Issue:
It seems that I am missing a serious concept of the shell builtin bind:
Mac Shell: ~/> $ bind '"4~":"for x in $(); do blah; done"'
# This is my F12 key
Mac Shell: ~/> $ fx in $(); do blah; doneor
This serves no purpose for me other than learning how to use bind.
Note: The or in for along with the ::space:: following for ends up going to the end of the line.
Question:
Can anybody point me in the correct direction as to what I am doing wrong? I checked man bash # shell builtin section and man bind to no avail.
Bash version:
Mac Shell: ~/> $ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)
Copyright (C) 2007 Free Software Foundation, Inc.
Thanks for your time!

This was being caused due to improperly quoted ANSI color schemes in my PS1 variable. Essentially I needed \[ & \] around each color code to prevent a miscalculation of bash prompt length.
Thanks everyone for attempting to help me with this issue.

Related

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.

Parameter substitution bad substitution error on macOS High Sierra

The ${parameter[^|^^|,|,,][pattern]} parameter substitution is giving me a bad substitution error.
$ echo $greeting
hello world
$ echo "${greeting^}."
-bash: ${greeting^}.: bad substitution
I updated to the latest bash version and keep getting the error.
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.3.0)
I've looked everywhere and the only suggestion I've found is making sure it's running bash 4.
$ echo $SHELL
/bin/bash
I'm running macOS High Sierra.
Your default shell is not the bash shell (downloaded from brew install bash) that contains the v4 which supports the parameter expansion syntax you are referring to.
On macOS echo $BASH_VERSION will tell you the version of the current shell. bash --version tells you the version of the first bash in your $PATH. So the way you were looking at the version was not telling you the version that you were running.
You need to add the recent version of bash to the file /etc/shells as the last line and use the command to set the shell as the default on Terminal
chsh -s /usr/local/bin/bash "$USER"
After this close and re-open the Terminal to make it effect. Without adding this default option in your Terminal, you could only use the recent bash only on scripts with interpreter she-bang set to #!/usr/local/bin/bash
See also this Ask Different answer to - Update bash to version 4.0 on OSX

bash tabbing for autocompletion escapes $

In shell (GNU bash, version 4.2.47(1)-release (x86_64-suse-linux-gnu)), when I hit tab for autocompletion, the "$" is escaped after the variable name is completed, but if there is no completion then it just bells. E.g.
$ ls $JDK_H<tab>
results in
$ ls \$JDK_HOME (with a trailing space)
On an old GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu), it did not escape the "$" after completion which is what I would like.
Is there a way to get that old behavior without strong side-effects? My BASHOPTS and SHELLOPTS are:
# (indented for readability)
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote
:force_fignore:histappend:interactive_comments:login_shell
:progcomp:promptvars:sourcepath
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history
:interactive-comments:monitor
Thanks. I am using SLES SP11.
--UPDATE. Other completions seem to work as usual, e.g. cd or echo do not escape the $. I also momentarily commented out /etc/share/bash-completion/bash_completion from my /etc/bash.bashrc which stopped $-escaping. So it appears like some kind of complete config issue.
Recent bash versions introduced some compatibility issues regarding this. Try like this:
complete -r # temporarily disable all completion rules
shopt -s direxpand
Links to similar problems reported to the bug-bash mail list:
http://lists.gnu.org/archive/html/bug-bash/2014-01/msg00062.html
http://lists.gnu.org/archive/html/bug-bash/2015-08/msg00176.html

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.

Mac Bash doesn't seem to have skip-completed-text variable

While Googling for another bash tip, I found this page on .inputrc http://ss64.com/bash/syntax-inputrc.html, which exactly fixed what I was trying to do (put a trailing / on symlinks to directories), but as I read further, I saw that there was a way to skip completed text as well. "Awesome", I said to myself, "this bugs me about twice a week". So, I put that into my .inputrc as well, but it doesn't work, or even seem to recognize what's going on. After logging out, and logging back in, this is what I'm seeing:
$ tail .inputrc
set mark-symlinked-directories on
set skip-completed-text on
$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
Copyright (C) 2007 Free Software Foundation, Inc.
$ bind -V | grep completed
$ bind -V | grep skip
$
That is, bash doesn't seem to recognize it's there at all... Is there something wrong with the version of bash supplied in Mountain Lion? Anything blindingly obvious I've forgotten to do?
skip-completed-text is new to bash version 4.
The: skip-completed-text is only in bash4.
On my Mac:
$ bash --version
GNU bash, version 4.2.37(2)-release (i386-apple-darwin12.1.0)
If you want install some opensource utilities i recommending you using macports (www.macports.org). Installing macports will give you one command called port and with it you can install things dead simply, like:
$ port install bash
will install bash 4 for you.
Bash v4 won't make it to OSX. Might I suggest zsh, which is not GPL3.

Resources