1

I would like to create a function or alias or command completion in bash which would take a command as "dfk-1234" or "DFK-nnnnn" (the number can be 1 to 5 digits, not zero-padded), and run a command "dfkp DFK-nnnn".

Arguments should be passed through verbatim. "dfk-18875 cat file.txt" should become "dfpk DFK-18875 cat file.txt".

I think command completion or tab expansion would work, but can't figure how to do it when the number changes.

What's the best way to do this? Once I can handle the main command name, then I can handle the rest (case, arguments, etc).

5
  • Background, attempting to reduce repetitive typing when using a work tool.
    – cde
    Aug 24, 2018 at 15:33
  • Wouldn't it be easier to do autocompletion for dfk 18875 instead? That's same amount of typing.
    – weirdan
    Aug 24, 2018 at 15:43
  • No, because we extensively use the project number, and that would mean copy paste would not work. I could easily handle it without the hyphen @weirdan wouldn't even have to ask, that's been asked to deth. I know bash can handle this, just not how.
    – cde
    Aug 24, 2018 at 16:00
  • Could you clarify what's wrong with dfk 12345? You could write a function called dfk which would then take the first argument as the target number and run dfpk DFK-12345 as requested. What's missing in that approach?
    – terdon
    Aug 24, 2018 at 17:10
  • @terdon We normally share the project number as DFK-12413. I then copy, and paste it. To do dfk 12345 would mean I then have to backspace and delete the hyphen. Or type dfk then paste it. I want to avoid all that. I can easily write a function as you describe. I want to just paste and hit enter.
    – cde
    Aug 24, 2018 at 17:30

1 Answer 1

2

Bash 4.0 introduced new functionality for handling commands that are not found -- it will call a function named command_not_found_handle, if that function exists. You could use that behavior to intercept calls to "programs" named dfk-NNN or DFK-NNN and re-run them as you like. Since we're depending on 4.0 behavior already, I've used the upper-casing and lower-casing parameter expansion features as well.

command_not_found_handle() {
  case "${1,,}" in
        (dfk-?|dfk-??|dfk-???|dfk-????|dfk-?????)
                echo dfkp "${1^^}" "${@:2}"
                return 0
        ;;
        (*)
                printf 'bash: %s: command not found\n' "$1" >&2
                return 127
        ;;

  esac
}

If you enter a command that doesn't exist, bash calls this function with the original command-line. The case statement lower-cases the first argument so that it's simpler to compare it against the dfk patterns required.

If the command starts with dfk- and ends with 1, 2, 3, 4, or 5 characters (tighten this to be digits as you see fit), then it -- currently echos, for debugging, but then -- calls the dfkp program with the first parameter being the upper-cased version of the initial dfk entry, followed by the remainder of the command-line.

For commands that don't match dfk-NNNN, it falls through and prints a simulated bash error message to stderr and returns 127. (This matches the default behavior, as if command_not_found_handle did not exist).

A sample session (with the echo debugging installed, as I don't have an actual dfkp program):

$ dfk-1234
dfkp DFK-1234
$ dfk-18875 cat file.txt
dfkp DFK-18875 cat file.txt
$ some-other-command
bash: some-other-command: command not found
$ dfk-1
dfkp DFK-1
$ dfk-12345
dfkp DFK-12345
2
  • That seems to be exactly what I want. I don't even need to do the single character wildcard, since the program itself has error handling for that. Simply match for (dfk-*). I'll leave this open for a bit in case someone else has a better solution, but +1.
    – cde
    Aug 24, 2018 at 20:06
  • Tested and works brilliantly.
    – cde
    Aug 24, 2018 at 21:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .