4
#!/bin/python
import os
pipe=os.popen("ls /etc -alR| grep \"^[-l]\"|wc -l")         #Expr1
a=int(pipe.read())
pipe.close()
b=sum([len(files) for root,dirs,files in os.walk("/etc")])  #Expr2
print a
print b
print "a equals to b ?", str(a==b)  #False
print "Why?"

Expr1の関数とExpr2の関数の違いは何ですか?Expr1が正しい答えを出すと思いますが、確かではありません。

4

3 に答える 3

4

簡潔な答え:

ls -laR | grep "^[-l]"ディレクトリへのシンボリックリンクをカウントします。で始まり、lディレクトリへのシンボリックリンクを含むすべての行に一致します。

対照的に、[files for root, dirs, files in os.walk('/etc')] ディレクトリへのシンボリックリンクはカウントされません。すべてのディレクトリを無視し、ファイルのみを一覧表示します。


長い答え:

これが私が矛盾を特定した方法です:

import os
import subprocess
import itertools

def line_to_filename(line):
    # This assumes that filenames have no spaces, which is a false assumption
    # Ex: /etc/NetworkManager/system-connections/Wired connection 1
    idx = line.rfind('->')
    if idx > -1:
        return line[:idx].split()[-1]
    else:
        return line.split()[-1]

line_to_filenameの出力でファイル名を見つけようとしますls -laR

これはexpr1andを定義しexpr2、コードと本質的に同じです。

proc=subprocess.Popen(
    "ls /etc -alR 2>/dev/null | grep -s \"^[-l]\" ", shell = True,
    stdout = subprocess.PIPE)         #Expr1
out, err = proc.communicate()
expr1 = map(line_to_filename, out.splitlines())

expr2 = list(itertools.chain.from_iterable(
    files for root,dirs,files in os.walk('/etc') if files))  #Expr2

for expr in ('expr1', 'expr2'):
    print '{e} is of length {l}'.format(e = expr, l = len(vars()[expr]))

expr1これにより、 からも含まれている名前が削除されexpr2ます。

for name in expr2:
    try:
        expr1.remove(name)
    except ValueError:
        print('{n} is not in expr1'.format(n = name))

expr1expr2が共有するファイル名を削除した後、

print(expr1) 

収量

['i386-linux-gnu_xorg_extra_modules', 'nvctrl_include', 'template-dkms-mkdsc', 'run', '1', 'conf.d', 'conf.d']

次に、findこれらのファイルを見つけて、これらのファイルの/etc何が異常なのかを推測しようとしました。それらは (ファイルではなく) ディレクトリへのシンボリック リンクでした。

于 2012-08-10T21:48:25.860 に答える
1

walk を使用すると、エラーは無視され (これを参照)、ls はエラーごとにメッセージを送信します。これらは単語としてカウントされます。

于 2012-08-10T20:32:55.537 に答える
0

私のマシンでは、/etcは/private / etcへのシンボリックリンクであるためls /etc、出力は1行だけです。ls /etc/との間の期待される同等性を与えlsますos.walk

于 2012-08-10T20:43:36.383 に答える