How to invoke a shell built-in explicitly?

I want to customize the functionality of cd command as per my needs.

I defined the following function –
function cd () { cd "[email protected]" && pushd "[email protected]"; }

The intent of this function is to automatically push the directory onto the stack so that it saves me the effort to manually type pushd . every time.

However, the above function is an infinitely recursive function, as the call to cd is interpreted to be the function itself and not the cd built-in.

How do I reference the cd built-in in this function?

I know that aliases can be escaped using . What is the way to escape functions or reference built-ins in a more explicit way?

Note: I do not want to rename my function to anything else.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Bash has a (builtin) command builtin, which does exactly what you need. Replacing cd with builtin cd in your function will fix the recursion.

Method 2

The command builtin forces a command name to be interpreted as a built-in or external command (skipping alias and function lookup). It is available in all POSIX shells including bash.

cd () { command cd "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="527612">[email protected]</a>" && pushd "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="012541">[email protected]</a>"; }

(Note that this example is a bad one: it doesn’t work with relative paths, and you might as well just type pushd in the first place.)

In bash and zsh (but not ksh), you can use builtin to force a command name to be interpreted as a builtin, excluding aliases, functions and external commands.

Method 3

I suspect when you say you “don’t want to rename your function to anything else,” you mean that you want to be able to call your function by the same name as the original command.

So, another way to do this that also works for things that aren’t built-ins, is to name your function something else, and then define an alias for the wrapped command. This works because the alias doesn’t exist in the execution context of your function.

Example wrapper.sh:

#!/bin/bash
function my_wrapper() { wrapped_program <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="527612">[email protected]</a> && dostuff }

And in, e.g., .bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

But this is pretty hacky. Using command is preferable when possible.

Method 4

For this to work with relative paths, the following would be needed:

function cd { 
   dir="$(realpath "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d1f591">[email protected]</a>")"
   command cd "$dir"
   pushd "$dir"
}

This assumes you are on a modern enough Linux distro which contains the ‘realpath’ utility. (RHEL 6 does not for instance). If Perl is available, ‘realpath’ can be simulated using:

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath("$1") . "\n";"
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x