2

in my .bash_profile I have extra command :

trash () { command mv "$@" ~/.Trash ; }

It's basically my safe rm. Unfortunately sudo doesn't work on it. I've looked up a fix for that and added alias sudo='sudo ' to my .bash_profile and while it works with every alias I have as you can see it's a custom command/function and if I use my now "custom" sudo on it I get this :

sudo: trash: command not found

Does anyone know a fix for that?

I am running MacOS Mojave.

Victor
  • 21
  • 2
  • sudo is using exec, so you need to have executable file with name trash. Try creating ~/bin directory, add it to $PATH and create a bash script in that directory instead of function. It's always good idea to have local bin directory where you can put bash script. – jcubic Feb 15 '19 at 11:25
  • Unfortunately it didn't work. – Victor Feb 15 '19 at 11:50
  • @Victor Why didn't it work? sudo couldn't find the new script? – Xen2050 Feb 15 '19 at 12:08
  • @Xen2050 Yes. I got the same error : `sudo: trash: command not found`. – Victor Feb 15 '19 at 12:17

3 Answers3

0

It looks like there's no easy solution, perhaps because sudo can be rather dangerous & has some strict security precautions. But a few more elaborate solutions could be:

  • With a little extra work, you could use declare to "rebuild" the function in sudo [source]:

       function hello()
        {
            echo "Hello!"
        }
    
        FUNC=$(declare -f hello)
        sudo bash -c "$FUNC; hello"
    

    Or more simply:

        sudo bash -c "$(declare -f hello); hello"
    

    But I think you'll have some trouble getting the arguments to the function, so in this case you'll have to use another answer below.

  • This answer looks interesting:

    I've written my own Sudo bash function to do that, it works to call functions and aliases :

    function Sudo {
    local firstArg=$1
    if [ $(type -t $firstArg) = function ]
    then
      shift && command sudo bash -c "$(declare -f $firstArg);$firstArg $*"
    elif [ $(type -t $firstArg) = alias ]
    then
      alias sudo='\sudo '
      eval "sudo $@"
    else
      command sudo "$@"
    fi
    }
    
  • If you can use su instead, it should support exported functions [source]:

    your_function () { echo 'Hello, World'; }
    export -f your_function
    su -c 'your_function'
    
  • If you've already moved the function to it's own executable file, it's possible (probable?) that sudo doesn't have the same $PATH as your interactive terminal, so you might need to edit your /etc/sudoers file, or do this [source:

    Give sudo your current PATH with:

    sudo env "PATH=$PATH" your_command
    

    Or in an alias: alias sudo='sudo env "PATH=$PATH" '

  • I think you could even source your whole .bash_profile with sudo, integrated into one of the answers above.

Xen2050
  • 13,643
  • 4
  • 24
  • 42
0

Here is a slight change to your request which works well on my old OS X:

trash(){ x=''; [[ $1 = s ]] && { x=sudo; shift; }; $x mv "$@" ~/.Trash; }

Without sudo:

trash file-1 file-2 etc

With sudo:

trash s file-1 file-2 etc

0

In this case, you want your bash function to essentially work like a standalone script. Using it as a bash_alias doesn't work because sudo isn't aware of it. When you do sudo trash somefile, it looks for that script in /root/.bash_alias, not /home/youruser/.bash_alias. Because this function only exists as a bash_alias in your own user's home directory, sudo/root says it doesn't exist. All you need to do is make your function available to all users, including sudo (root).

You can get around this by either adding your alias to the end of your /etc/profile file which would make all users globally aware of the function, or you can create a bash script at /usr/bin/trash to perform the same essential function. In the later scenario, you would also want to do sudo chmod 755 /usr/bin/trash so that all users could execute the program.

Either way would work in your case, but I suggest the /etc/profile method, since it's just a simple alias function for moving files to trash. There's no reason to restrict it for other users. Always remember to consider the security implications of making a bash_alias available to all users.

Hope that helps. :)

True Demon
  • 36
  • 4