web-dev-qa-db-ja.com

親シェルの作業ディレクトリをプログラムで変更することは可能ですか?

私が通常行くディレクトリに切り替えるためのコードを書きたいのですが。このプログラムがmycdで、/a/very/long/path/nameが移動先のディレクトリだとします。

したがって、mycd 2の代わりにcd /a/very/long/path/nameと入力するだけです。ここでは、mycd2がその/a/very/long/path/nameを参照していることを知っていると想定しています。 mycd 1mycd 3、...などもあります。

問題は、シェルスクリプトとしてmycdを記述し、. mycd 2と入力して必要なことを行う必要があることです。私が実際に気にかけていること。

私の質問は:

  • sourceを使用せずにそれを行うことができますか? . mycdmycdがシェルスクリプトである必要があると想定しているため、これにより、不要な関数が導入される可能性もあります。

  • 他のプログラミング言語で実装できますか?

8
Javran

mycdを関数にして、cdコマンドが現在のシェルで実行されるようにします。 〜/ .bashrcファイルに保存します。

function mycd {
    if (( $# == 0 )); then
        echo "usage: $FUNCNAME [1|2|3|...]"
        return
    fi
    case $1 in
        1) cd /tmp ;;
        2) cd /a/very/long/path/name ;;
        3) cd /some/where/else ;;
        *) echo "unknown parameter" ;;
    esac
}
23
glenn jackman

シェルの現在のディレクトリを別のプロセスから変更することはできません。現在のディレクトリを変更できるのは、プロセス自体だけです。これは、環境変数やファイル記述子など、他のいくつかの特性にも当てはまります。

chdir システムコールを介してptraceシステムコールを実行させることにより、別のプロセスの現在のディレクトリに影響を与えることが実際に可能です。これにより、デバッガーが機能します。ただし、プロセスが実際の現在のディレクトリと一致する必要があるいくつかの内部データ構造を維持している場合、プログラムはクラッシュする可能性があります。シェルの場合、このアプローチは機能する機会がありません。

シェル自体によってコードが実行されるように準備する必要があります。続行する通常の方法は、それをシェル関数にして~/.bashrcに格納することです。配布したいコードなどが原因でこれが不可能な場合は、関数定義を含むシェルソースファイルを記述し、対話型シェルに .コマンド

ご指摘のとおり、シェルスクリプトは常にサブシェルで実行され、親シェルに影響を与えることはできません。

ただし、次のことができます...

  • エイリアスを使用:
    _alias mycd2='cd /a/very/long/path/name'_
  • あなたのスクリプトを持っています1 有効なシェルコマンドを出力する...

    _#!/bin/bash
    if [ "x$1" = "x2" ]
    then
        echo "cd /a/very/long/path/name"
    fi
    _

    ...そしてその出力を実行します:$(mycd 2)

1:例では、case条件ではなくifステートメントを使用することをお勧めします。

5
n.st