Script that affects the interactive shell that launched it

I wrote this script to be able to quickly go to n:th directory in an ls output:

#!/usr/bin/env bash
# cd to the nth directory in a list as produced by ls
cd $( ls | head -n$1 | tail -n1 )

I named it cde and made it executable (it's in my $PATH) so now I can use

. cde 3

to change to the 3:rd directory for example (ie I source it). Because of how bash creates subshells for scripts I cannot just execute it like

cde 3

since only the directory of the subshell is affected.

How would you do to get rid of having to write that extra dot and still get the desired behaviour?

I would have used an alias for this instead of a script, but I couldn't figure out how since I don't know how to pass arguments to aliases.

1 answer

  • answered 2018-07-11 04:15 Anton

    Use a function instead of a script or an alias!

    Functions are way more flexible than aliases, and does not create subshells like executing scripts do. Thus the change of directory is going to affect your interactive ("current") shell.

    You can define a function to do this like so:

    # cd to the nth directory in a list as produced by ls
    function cde {
    cd $( ls | head -n$1 | tail -n1 )
    }
    

    Put the fuction definition in your ~/.bash_aliases file (or some other file that gets sourced upon terminal startup, like ~/.bashrc), and you won't have to define it manually each session.

    It will give you the desired behaviour.