0

We recently migrated from HP-UX B.11.31 to Linux 3.10.0-1160.15.2.el7.x86_64.

I am trying to achieve the below (which worked in the earlier HP-UX system):

$ pwd
/global/app/opt/prod/ee/01/custo/src/
$ cd prod qa
/global/app/opt/qa/ee/01/custo/src/
$ pwd
/global/app/opt/qa/ee/01/custo/src/

Basically, it switches from prod to qa, maintaining the relative directory structure.

when I try the same think in Linux:

$ pwd
/global/app/opt/prod/ee/01/custo/src/
$ cd prod qa
-bash: cd: prod: No such file or directory
$ pwd
/global/app/opt/prod/ee/01/custo/src/

Here, the directory doesn't change.

Please help.

3

3 Answers 3

2

Such substitution is a function offered by the ksh shell.

The bash shell does not offer it.

Try switching over to kshto resolve this.

$ pwd
/tmp/steve
$ cd ve phen
bash: cd: ve: No such file or directory
$ ksh
$ pwd
/tmp/steve
$ cd ve phen
/tmp/stephen
$
5
  • 2
    ... inherited by zsh as well I think Commented Jul 10, 2021 at 18:12
  • 1
    hi steve, HP-UX is using sh and Linux is using bash (checked using echo $0) Commented Jul 10, 2021 at 18:12
  • 1
    Thanks @steve! switching to ksh (exec ksh) gave me desired results. Sorry cannot upvote your answer. No reputation :( Commented Jul 10, 2021 at 18:25
  • 1
    Hmm... is ksh (as opposed to sh) really often just a symlink to bash though? Isn't $SHELL just telling you your login shell here? Commented Jul 10, 2021 at 19:29
  • @AmanS.Aneja Good! If this solves your issue, please consider accepting the answer. Accepting an answer marks the issue as resolved.
    – Kusalananda
    Commented Jul 10, 2021 at 20:36
0

I'm not exactly sure about the semantics of that two-argument cd, but something like this might do for the simple cases. This changes the string in the first argument to the string in the second argument the first time it appears in the current directory, and prints the new directory name.

#!/bin/bash
cdsub() {
    if [ "$#" = 2 ]; then
        local dir="${PWD/"$1"/"$2"}"
        printf "%s\n" "$dir"
        cd -- "$dir"
    else
        printf "usage: cdsub <string> <replacement>" >&2
    fi
}

So,

$ cd /tmp/foo/foo
$ pwd
/tmp/foo/foo
$ cdsub foo bar
/tmp/bar/foo
$ pwd
/tmp/bar/foo

You could name the function cd, and then use command cd inside to avoid sinking into endless recursion, but Bash's cd takes the -L and -P options too, and we'd need to implement proper argument processing for them, too. Just checking the number of arguments would make something like cd -P directory try to do the replacement.

Also, the above function doesn't deal with errors too well, e.g. cd xyz something where xyz doesn't appear in the path would just leave you in the current directory instead of erroring like Ksh does.

0

A bash implementation for .bashrc:

# ksh-like change directory
# if two args, do substitution in PWD
cd_ksh () {
  if [ "$#" -ne 2 ]; then builtin cd $1; return; fi
  echo "   cd_ksh: substituting $1 with $2 in PWD"
  newdir=${PWD//$1/$2}
  builtin cd $newdir
}
export -f cd_ksh
alias cd=cd_ksh

This will result in the same return value as the builtin cd command in all cases

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .