3

I just imported my git config onto my new laptop running Ubuntu20.04, but for some reason few of my git aliases using Bash read built-in now fail.

[alias]
    try = "!read -t 5 -n 1 -p 'Confirm? [Y|n] '"
$ echo "$SHELL, $(git --version)"
/bin/bash, git version 2.25.1

$ GIT_TRACE=1 git try
23:57:46.840752 git.c:703               trace: exec: git-try
23:57:46.840829 run-command.c:663       trace: run_command: git-try
23:57:46.841147 run-command.c:663       trace: run_command: 'read -t 5 -n 1 -p '\''Confirm? [Y|n] '\'''
read -t 5 -n 1 -p 'Confirm? [Y|n] ': 1: read: Illegal option -t

This thread suggests that sh is invoked in which case there is no -t option to the read built-in.

Given it used to work on my previous laptop ... instead of relying on some workarounds like prepending the alias command with bash -c, is the shell being used here something that can be configured?

Thank you.

Stphane
  • 3,368
  • 5
  • 32
  • 47
  • 5
    `instead of relying on some workarounds like prepending the alias command with bash -c` That not a workaround, that's the solution. Using `read -t` without `bash -c` is a workaround. If you want to use bash `read` then use bash. | What does `sh --version` return on your ubuntu? – KamilCuk Apr 15 '21 at 22:22
  • @KamilCuk `sh --version` returns `sh: 0: Illegal option --` – Stphane Apr 15 '21 at 22:39
  • 2
    Great, because `sh` on ubuntu is dash. Ex. https://unix.stackexchange.com/questions/442510/how-to-use-bash-for-sh-in-ubuntu etc. – KamilCuk Apr 15 '21 at 22:48
  • Interesting [answer here about Dash](https://askubuntu.com/a/976504/587287). – Stphane Apr 16 '21 at 10:28

3 Answers3

1

In general, on Linux, the way to make sure a particular interpreter runs a particular script—script here meaning commands stored in a file that is marked executable—is to have the file start with #! followed by the path-name of the interpreter. (You can put a single space between the #! and the interpreter, and I normally do.)

In this case that would mean using a script instead of an alias. Name your program git-try, put it in a directory that is on your $PATH, and git try will run your git-try script. You can now have the script start with #! /bin/bash to make sure that it gets run with bash.

If you really want it to be an alias instead of a script, the correct solution is to invoke bash -c, as KamilCuk said in a comment.

(Sometimes interpreters move around, so #! /usr/bin/env python3 is a way to work around the problem of not knowing whether python3 will be in /usr/bin or /usr/local/bin. Since bash is usually in /bin/bash this is less of a problem here.)

torek
  • 448,244
  • 59
  • 642
  • 775
0

My previous laptop ran Fedora 33 where sh points to Bash. Whereas on the new laptop running Ubuntu, sh points to Dash as pointed out by @KamilCuk in a comment.

Now, there is no way to configure git to use a specific shell for aliases.

Stphane
  • 3,368
  • 5
  • 32
  • 47
0

There are a couple of alternatives to using bash -c in your aliases.

Firstly, you could set /bin/sh to point back to bash instead of dash. On Ubuntu you do this with:

sudo dpkg-reconfigure dash

Choose "Yes" in the dialog to keep it as dash and "No" to set it to bash. There will be a bit of a slowdown in some scripts and in startup, but it might not be noticeable for you. You can always set it back with the same command if you like.

Secondly, you could download the git source code with:

git clone https://github.com/git/git

and then replace all occurrences of /bin/sh with /bin/bash and compile your own custom version of git. This might seem a bit extreme, but what's the fun in running Linux if you don't do crazy things occasionally!

seumasmac
  • 2,174
  • 16
  • 7