3

私は独自のバージョンの「cd」コマンドを実装しようとしています。このコマンドは、ハードコードされたディレクトリのリストをユーザーに提示し、ユーザーはリストのエントリに対応する番号を入力する必要があります。今のところ名前が付けられているプログラムはmy_cd.py、ユーザーを選択したディレクトリに効果的に「cd」する必要があります。これがどのように機能するかの例:

/some/directory
$ my_cd.py
1) ~
2) /bin/
3) /usr
Enter menu selection, or q to quit: 2

/bin
$

現在、を使用して「cd」しようとしてos.chdir('dir')います。my_cd.pyただし、おそらく独自の子プロセスで開始されるため、これは機能しません。my_cd.py次の名前のソースbashスクリプトで呼び出しをラップしようとしましたmy_cd.sh

#! /bin/bash
function my_cd() {
    /path/to/my_cd.py
}

/some/directory
$ . my_cd.sh
$ my_cd
... shows list of dirs, but doesn't 'cd' in the interactive shell

これを機能させる方法についてのアイデアはありますか? 対話型シェルの現在のディレクトリを Python スクリプトから変更することはできますか?

4

5 に答える 5

7

ソースbashコードを次のように変更します。

#! /bin/bash
function my_cd() {
    cd `/path/to/my_cd.py`
}

cosmeticそして、すべての出力 (ユーザーへのメッセージ、メニューなど) を で実行する Python コードとsys.stderr、最後に の代わりに、ディレクトリを変更する必要があるパス(へ)os.chdirのみを実行します。printsys.stdout

于 2010-04-03T14:52:42.887 に答える
3

my_cd.py:

#!/usr/bin/env python
import sys

dirs = ['/usr/bin', '/bin', '~']
for n, dir in enumerate(dirs):
    sys.stderr.write('%d) %s\n' % (n+1, dir))
sys.stderr.write('Choice: ')
n = int(raw_input())
print dirs[n-1]

使用法:

nosklo:/tmp$ alias mcd="cd \$(/path/to/my_cd.py)"
nosklo:/tmp$ mcd
1) /usr/bin
2) /bin
3) ~
Choice: 1
nosklo:/usr/bin$ 
于 2010-04-03T14:50:42.977 に答える
2

これはできません。作業ディレクトリへの変更は、親プロセスには表示されません。せいぜい、Python スクリプトに変更先のディレクトリを出力させてから、ソース スクリプトを実際にそのディレクトリに変更させることができます。

于 2010-04-03T14:39:58.407 に答える
2

この質問には「bash」というタグも付けられているため、簡単な bash のみのソリューションを次に示します。

$ cat select_cd
#!/bin/bash

PS3="Number: "

dir_choices="/home/klittle /local_home/oracle"

select CHOICE in $dir_choices; do
   break
done

[[ "$CHOICE" != "" ]] &&  eval 'cd '$CHOICE

さて、このスクリプトは実行するのではなく、ソース化する必要があります。

$ pwd
/home/klittle/bin
$ source select_cd
1) /home/klittle
2) /local_home/oracle
Number: 2
$ pwd
/local_home/oracle

そう、

$ alias mycd='source /home/klittle/bin/select_cd'
$ mycd
1) /home/klittle
2) /local_home/oracle
Number:

あなたのケースを解決するには、ユーザーが実行するコマンドを bash スクリプトをソースとするエイリアスにすることができます。これは、最初にディレクトリの選択を行い、cd が完了した後に python プログラムに飛び込みます。

于 2010-04-03T15:36:18.620 に答える
1

言われたこととは反対に、プロセスイメージを 2 回置き換えることでこれを行うことができます。

bash で、my_cd 関数を次のように置き換えます。

function my_cd() {
    exec /path/to/my_cd.py "$BASH" "$0"
}

次に、Python スクリプトを次のように終了する必要があります。

os.execl(sys.argv[1], sys.argv[2])

import os, sysスクリプトの先頭にあることを忘れないでください。

ただし、これは境界ハックであることに注意してください。シェルが終了し、同じプロセスで実行されている python スクリプトに置き換えられます。Python スクリプトは環境に変更を加え、それ自体をシェルに置き換えますが、同じプロセスのままです。これは、以前のシェル セッションで他のローカルの未保存およびエクスポートされていないデータまたは環境がある場合、新しいものには保持されないことを意味します。また、rc および profile スクリプトが再び実行されることも意味します (通常は問題になりません)。

于 2010-04-03T19:27:47.377 に答える