如何从python脚本更改当前目录?

时间:2010-04-03 14:38:37

标签: python bash shell directory cd

我正在尝试实现我自己版本的'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')'cd'。但是,这不起作用,可能是因为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的当前目录?

5 个答案:

答案 0 :(得分:7)

将您的源代码bash更改为:

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

和您的Python代码在cosmetic上完成所有sys.stderr输出(向用户,菜单等发送消息),最后代替os.chdirprint(到sys.stdout)目录应该更改的路径。

答案 1 :(得分: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$ 

答案 2 :(得分:2)

这不可能。父进程看不到对工作目录的更改。最多可以让Python脚本打印要更改的目录,然后让源脚本实际更改为该目录。

答案 3 :(得分: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

现在,此脚本必须是source'd,而不是执行:

$ 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程序。

答案 4 :(得分: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脚本将再次运行(通常不是问题)。