Search code examples
bashcommand-lineunset

How to get builtin of the builtin command?


Out of curiosity, say you created this function:

cd () { echo 'hi'; }

Now, whenever you entered cd you'd get "hi" printed. In case, you wanted to use the original cd command, you could do the following:

builtin cd

But what if I also created this:

builtin() { echo 'haha, got ya!'; }

Now, how do you get the builtin command for either builtin or cd?


Solution

  • Okay first off don't override the builtin command, which I assume you're not doing on purpose. Given the fact that you can override all the builtins, I thought up a more ridiculous route:

    #!/bin/bash
    
    builtin() { echo "Ha"; }
    cd() { echo "Ha"; }
    pwd() { echo "foobar"; }
    
    result=$(/bin/bash --noprofile --norc -c "\\cd /home/cwgem/testdir; \\pwd; \\ls" )
    
    /bin/echo "$result"
    

    Result:

    $ bash test.sh 
    /home/cwgem/testdir
    test.txt
    

    The idea here is to:

    • Use absolute paths to functions which can't be overridden as a function (this of course goes under the assumption that you don't go messing around with /bin/bash and /bin/echo)
    • Utilize the fact that $() is syntactic command substitution and I wasn't able to override that
    • Calling bash with --noprofile and --norc, which are explicit in not sourcing in the usual files which might contain overrides
    • Finally \'s are added in front of commands in case aliases are floating around

    That said, all and all this hack was done out of academic curiosity and should not be applied in the real world.