shelljs / shx

Portable Shell Commands for Node
MIT License
1.73k stars 45 forks source link

Discuss: popd/pushd workarounds #121

Closed eteeselink closed 7 years ago

eteeselink commented 7 years ago

The README says that popd and pushd can't be used and don't have a workaround, but for many basic cases there is: Windows accepts forward slashes when you quote the path. So:

$ pushd "../backend" && some_program && popd

works the same on Windows and *nix. I'm not sure how well it'd work with expanding environment variables though, but I bet that for basic package.json oneliners you often don't need that.

Was this unknown knowledge, or is there a reason I'm not aware of why popd and pushd are shown to have no workarounds?

nfischer commented 7 years ago

pushd and popd are supposed to change your working directory (similar to cd), which involves modifying your shell process. shx (like all node programs) runs in a child process, so it is unable to modify its parent process. No matter how hard shx tries to change the working directory, that change will not carry through to the shell.

You can try this out at home:

$ cat my-cd-script.js
var shell = require('shelljs');
shell.cd('foo');

$ pwd && node my-cd-script.js && pwd # the cd() can't affect your shell's directory
eteeselink commented 7 years ago

I'm well aware, but we're talking about shx, not shelljs. For cd, the README lists the following recommended workaround:

Just use plain old cd (it's the same on windows too)

My point is that the same holds for pushd and popd. They're commands that work on both Windows and Unix, just like cd works on both. And that maybe we should add the fact that on Windows, when you double-quote the directory passed to cd or pushd, you can use forward slashes too, making for a cross platform command.

Of course, none of this has anything to do, strictly, with shx itself, but I assume you added that "workarounds" table column to the README for a reason :-)

ps. unrelated sidenote: on Windows (and not on UNIX, afaik) it is actually possible to change the parent process's working directory, in some cases, using a hack driven by batch files. It works because batch files don't actually spawn a child environment but run in the context of the environment that invokes them. I once used this in a little hobby project: https://github.com/eteeselink/cdhere

nfischer commented 7 years ago

My point is that the same holds for pushd and popd.

Ah ok, this is news to me. If this is the case, then I agree that we should list them as workarounds just like cd. Feel free to send a PR.

And that maybe we should add the fact that on Windows, when you double-quote the directory passed to cd or pushd, you can use forward slashes too, making for a cross platform command.

Are double quotes required? This stackoverflow seems to indicate that Windows cmd.exe has inconsistent support for forward-slash, even with quotes.

It works because batch files don't actually spawn a child environment but run in the context of the environment that invokes them

Right 😄 Wouldn't this be considered running in the same process though? On Unix, you can source a script, which executes it in the current process (hence why it can change current directory).

eteeselink commented 7 years ago

PR made!

About the side-note: yep! effectively, invoking a batch file on Windows works like sourcing a script on Unix. The thing is that this means that you could implement cd, popd, pushd and dirs inside shx on Windows. As long as the shx command is a batch file, it can change the working directory :-)

Not that I think there is any value to that, given that cd, pushd and popd work cross-platform. Plus I don't think there's a way to make it cross-platform. I'm really just rambling here :-)

nfischer commented 7 years ago

inside shx on Windows. As long as the shx command is a batch file

Anything's possible if you change the project 😜 In our case, we're a node module, so that will always run under a separate process.

eteeselink commented 7 years ago

Well, shx is a node module started by a batch file on Windows :-)

(node_modules/.bin/shx.cmd to be precise).

But anyway, the point is moot because, a) we can't do the same on UNIX and b) there's no use because cd, pushd and popd are sufficiently cross-platform. And who needs dirs in a package.json script, right?

nfischer commented 7 years ago

Fixed by #122