1

I have a shell and I use pwd to show in which directory I am. but when I'm in directory that it's a symlink it show the physical directory not the symlink

import subprocess as sub

def execv(command, path):
    p = sub.Popen(['/bin/bash', '-c', command],
                    stdout=sub.PIPE, stderr=sub.STDOUT, cwd=path)
    return p.stdout.read()[:-1]

If I have folder /home/foo/mime that it's symlink to /usr/share/mime when I call

execv('pwd', '/home/foo/mime')

I got /usr/share/mime

My code for shell look like this:

    m = re.match(" *cd (.*)", form['command'])
    if m:
        path = m.group(1)
        if path[0] != '/':
            path = "%s/%s" % (form['path'], path)
        if os.path.exists(path):
            stdout.write(execv("pwd", path))
        else:
            stdout.write("false")
    else:
        try:
            stdout.write(execv(form['command'], form['path']))
        except OSError, e:
            stdout.write(e.args[1])

And I have client in JavaScript

(probably returning result of the command and new path as JSON will be better).

Is there a way to make pwd return path to the symlink instead of the physical directory.

4

3 に答える 3

6

シンボリック リンクを使用して現在のディレクトリにアクセスしていることを認識しているのは、現在のシェルだけです。この情報は通常、子プロセスには渡されないため、実際のパスによってのみ現在のディレクトリを認識します。

この情報をサブプロセスに認識させたい場合は、引数や環境変数などを介して情報を渡す方法を定義する必要があります。シェルから PWD をエクスポートするとうまくいくかもしれません。

于 2012-06-15T10:19:21.520 に答える
3

shell=Trueで使用Popen:

import os
from subprocess import Popen, PIPE

def shell_command(command, path, stdout = PIPE, stderr = PIPE):
  proc = Popen(command, stdout = stdout, stderr = stderr, shell = True, cwd = path)
  return proc.communicate() # returns (stdout output, stderr output)

print "Shell pwd:", shell_command("pwd", "/home/foo/mime")[0]

os.chdir("/home/foo/mime")
print "Python os.cwd:", os.getcwd()

これは以下を出力します:

Shell pwd: /home/foo/mime
Python os.cwd: /usr/share/mime

pwd私の知る限り、上記のように実際にシェル自体に尋ねる以外に、Pythonでシェルを取得する方法はありません。

于 2013-03-11T16:27:35.320 に答える
3

シンボリック リンクを解決したい場合は、おそらく を使用することをお勧めしますpwd -P。以下は ZSH と BASH の例です (動作は同じです)。

ls -l /home/tom/music
lrwxr-xr-x  1 tom  tom  14  3 říj  2011 /home/tom/music -> /mnt/ftp/music

cd /home/tom/music

tom@hal3000 ~/music % pwd
/home/tom/music
tom@hal3000 ~/music % pwd -P
/mnt/ftp/music

FreeBSD の /bin/pwd を使用すると、次のようになります。

tom@hal3000 ~/music % /bin/pwd 
/mnt/ftp/music
tom@hal3000 ~/music % /bin/pwd -P
/mnt/ftp/music
tom@hal3000 ~/music % /bin/pwd -L
/home/tom/music

したがって、このバージョンはデフォルトで -P を想定しているため、シンボリックリンクを未解決にしたい場合は、pwd(1) が -L もサポートしている可能性があります。

于 2012-06-15T09:38:00.317 に答える