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
$

目前,我正在尝试使用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 脚本更改我的交互式 shell 的当前目录?

4

5 回答 5

7

将源代码更改bash为:

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

和您的 Python 代码在 上执行其所有cosmetic输出(给用户、菜单等的消息)sys.stderr,最后,而不是os.chdir,只是print(到sys.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-only 解决方案:

$ 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 脚本,该脚本首先进行 dir 选择,然后在 cd 完成后潜入 python 程序。

于 2010-04-03T15:36:18.620 回答
1

与所说的相反,您可以通过两次替换过程映像来做到这一点。

在 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在脚本的开头。

但请注意,这是边界黑客。你的 shell 死了,用 python 脚本替换自己,在同一个进程中运行。python 脚本对环境进行了更改,并用 shell 替换了自己,再次返回,仍然在同一个过程中。这意味着,如果您在上一个 shell 会话中有一些其他本地未保存和未导出的数据或环境,它将不会持续到新的。这也意味着 rc 和 profile 脚本将再次运行(通常不是问题)。

于 2010-04-03T19:27:47.377 回答