7

I have a simple script that I want to invoke 'pushed' followed by another command. But the 'pushd' command inside the script doesn't seem to stick past the script.

What's a way to make this execute in the shell terminal?

#!/bin/sh

pushd $1
time

What I really want to accomplish is invoke pushd followed by other-command with one command.

3 Answers3

8

A shell script normally executes in a separate instance of the shell program, /bin/sh in this case. Your pushd command affects that sub-shell's working directory only. If it were otherwise, any program you ran from the shell could mess with your shell's working directory.

To execute that script within the current shell, say this instead:

$ . my-command somedir

or, more verbosely:

$ source my-command somedir

To make it appear that your program works like any other, you can use an alias:

$ alias mycmd='source my-command'
$ mycmd /bin
$ pwd
/bin
Warren Young
  • 72,032
  • What I really want is execute 'pushd ' followed by another command that takes no params. I may not need a shell script for it - what's a good way to do this? –  Dec 29 '10 at 00:23
  • @sarah-soto All you need then is pushd <params>; other-command – Shawn J. Goff Dec 29 '10 at 00:26
  • I should have clarified: I want a shortcut so I am invoking both commands one after the after without implicitly calling both. I can't aliase the two commands to be alias p2='pushd; other-command' and then invoke 'p2 ~/temp' as the shell will return the error: '-bash: pushd: no other directory –  Dec 29 '10 at 00:38
  • You could use a shell function: function p2 () { pushd "$@"; other-command;} – Steven D Dec 29 '10 at 00:46
  • 2
    A shell script is a fine way to do this. It's inefficient, but this is not a case where optimization is worth bothering with. Defining a shell function in your ~/.bash_profile (or whatever your shell uses, if not Bash) will also work. Your choice. – Warren Young Dec 29 '10 at 03:10
  • I tried to define a shell function in my bash_profile - but should I alias the function as well? I tried this: alias pd2='function p2() { pushd "$@"; other-command;}' but upon running it as 'pd2 ~/Documents', I get the error: -bash: syntax error near unexpected token `~/Documents/' –  Dec 29 '10 at 19:09
  • No, don't alias the function. The function option is an alternative to shell script + alias. Your other problem is due to the double-quotes, which are preventing Bash from interpreting the ~ in your directory. You can remove them, in which case you won't be able to use this function with directories with spaces in their names, or you can avoid using the p2 command with wildcards, ~, or anything else handled by the shell. There's a third alternative, writing a much more clever p2() function (or script). – Warren Young Dec 29 '10 at 20:21
2

Scripts cannot alter their parent processe's environment. Because of this, any environment changes made in the script are lost.

To run the script in the same process, you can 'source' the script like this

. /path/to/script.sh args
Shawn J. Goff
  • 46,081
0

Instead of a shell script, function is more appropriate for this kind of operation, especially when using pushd.

Add this in .bashrc:

foo() {
    pushd $1
    time
}
export foo

In shell:

$ foo mydir1

output:

~/mydir1 ~

real    0m0.000s
user    0m0.000s
sys     0m0.000s
otter.pro
  • 707