1

I'm making some simple logging tools to use for work and i have a niche problem that i'm trying to solve when typing commands in a shell. I want to, as smoothly as possible, use a function's result for the argument of another command, all while keeping it inline. For example:

sudo some-command --output "<my-function>_log.txt"    <tab><tab> =>
sudo some-command --output "2021_project_a_log.txt"

I want to expand, or rather execute, my-function while writing some-command. The double tab is just to get the use across, that's what i mean by "inline" but i might be misusing that term. I don't want to split the command, i.e. execute my-function, store the variable or use the stdout, and then type some-command. The functions print meta data basically such as project name, timestamps etc. I will use them to name and store the output from various commands and tools.

These are the ways i've found so far that works:

  • I can write "`my-function`_log.txt"
  • I can write "$(my-function)_log.txt"

These two can then either be used as is (in which case i cannot check them first) or i can use the shortcut Ctrl + Alt + E to use shell-expand-line to expand them but this has the following problems that i try to get around:

  • All functions (OK) and all aliases (not OK) are expanded
  • Quotes are removed and since i will be using this type of expansion for string input that can break things

I don't want to expand all aliases as some of them can be long and unnecessary which will clutter the prompt.

Question:

Is there a way to expand, such as with Ctrl + Alt + E, only the selected function or the function that's under the cursor or something? Alternatively, can i block certain aliases from being expanded?

Thanks!

1
  • You can 'block' an alias temporarily by using \alias, and it will disable it and use the function name. Aliases take precedence over functions with the same name. type <command> shows the function. command <command> will run the builtin command even if it has an alias and a function with the same name.
    – alchemy
    Feb 17, 2022 at 20:17

1 Answer 1

2

Three steps:

  1. Define a completion function for your main program (for you is sudo) File: _sudo_completions.env

    #! /bin/bash
    
    _sudo_completions()
    {
        local SOME_COMMAND="echo"
        if [[ "${COMP_WORDS[1]}" == "${SOME_COMMAND}" ]]; then
            if [[ "${COMP_WORDS[2]}" == "--output" ]]; then
                if [[ "${COMP_WORDS[3]}" =~ ^\"[^\"]+_log.txt\"$ ]]; then
                    CMD="${COMP_WORDS[3]%_log.txt\"}"
                    CMD="${CMD#\"}"
                    CMD_RESULT=$(${CMD})
                    COMPREPLY="\"${CMD_RESULT}_log.txt\""
                fi
            fi
        fi
    }
    
    complete -F _sudo_completions sudo
    

    Of course, change value of "SOME_COMMAND" variable with your "sudo" sub-command.

  2. Load this precedent file

    . _sudo_completions.env
    

    You can put this line in your .bash_profile file

  3. Use it!

    sudo echo --output "my_fct_log.txt" <tab> <tab>
    

You must log in to answer this question.

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