pushd and popd are commands which change the current working directory. In contrast, variables like $PWD are expressions, which are far more flexible. For example, we can run commands like `diff "$OLD_PWD/foo" "$PWD/bar"` which reference multiple directories. Doing that with pushd/popd would be weird, e.g. `diff "$(popd; echo "$PWD/foo")" "$PWD/bar"`
a) if pushd fails you are doing things not in the target directory, and when you call popd you are now in a totally wrong place. set -o errexit should handle this, but there could be situations (at least theoretically) when you disable it or didn't enable it in the first place
b) you need to mentally keep the stack in your head when you write the script. And anyone else who would be reading your script. (Edit: including yourself a couple of months/years later)
c) pushd $script_invocation_path is easier to understand and remember.
Eg:
$global:MainScriptRoot = $PSScriptRoot
$global:configPath = Join-Path $PSScriptRoot config
$global:dataPath = Join-Path $PSScriptRoot data
$dirsToProcess = gci -Path $PSScriptRoot -Directory | ? Name -Match '\d+-\w+' | Sort-Object Name
foreach ($thisDir in $dirsToProcess) {
foreach ($thisFile in $moduleFiles) {
. $thisFile.FullName
}
}
It's PowerShell, but the same idea. I use it in a couple of scripts, which call other scripts.
Why not use pushd/popd instead?