Jang
Jang

Reputation: 23

python's subprocess.check_call says a nonempty file is empty

I tried to print the number of line using 'wc -l' command using subprocess. It outputs that the file is empty while it is not.

import os
import subprocess
import tempfile
import time

filename = '/tmp/aaaaa'

with open(filename, 'w') as fout:
    fout.write('1')

with open(filename) as fin:
    print(fin.readlines())

subprocess.check_call('wc -l {}'.format(filename), shell=True)

Output:

['1']
0 /tmp/aaaaa 

Why does it happen? My python version is 2.7.16.

Upvotes: 2

Views: 145

Answers (2)

user14069211
user14069211

Reputation:

You do not need to spawn an external process in order to count the number of lines in a file. As you are noticing with readlines, if you use python's builtin handling of text files, the lines that are read in will also include any final line without a terminating newline character, so the problem encountered using wc -l does not arise. You can use a generator to convert this into a recipe that is suitable for counting the lines in a file without reading the whole file into memory at the same time.

with open("filename") as fin:
    num_lines = sum(1 for _ in fin)

If you are only interested in testing whether a file is empty, you could just read the first byte:

with open("filename", "rb") as fin:
    is_empty = not fin.read(1)

or you could use the file metadata:

is_empty = os.path.getsize(filename) == 0

Upvotes: 0

Pynchia
Pynchia

Reputation: 11606

As said in the comments, you lack at least a newline.

wc -l counts the lines present in the file.

Assuming that is what you desire, you need to create a line:

with open(filename, 'w') as fout:
    fout.write('1\n')

To make it independent of the OS do

import os

with open(filename, 'w') as fout:
    fout.write('1'+os.linesep)

See this similar QA for more info

If you don't need a line, check out how to test if a file is empty in bash

Upvotes: 2

Related Questions