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).

  • Background, attempting to reduce repetitive typing when using a work tool. – cde Aug 24 '18 at 15:33
  • Wouldn't it be easier to do autocompletion for dfk 18875 instead? That's same amount of typing. – weirdan Aug 24 '18 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 '18 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 '18 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 '18 at 17:30
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
  • 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 '18 at 20:06
  • Tested and works brilliantly. – cde Aug 24 '18 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.