3

I came across a if statement like this:

if [ -f <file path> -size +0 ] 

I know that -f checks for file existed, but what does this -size +0 do here?

I can't get help form man page also tried searching forums, little curious to find this help me.

2
  • 1
    It will most likely result in an error. Commented Mar 1, 2016 at 5:15
  • @llua I tried executing this and i don't see any error Commented Mar 1, 2016 at 6:47

2 Answers 2

4

Most likely, this is erroneous. The form -size +0 is legal for the find standard utility (and means a non-empty file), but not for test (a.k.a. [). It seems that the script author reused it without keeping proper context. If this is ksh, it should have the following check:

–s file True, if file exists and has size greater than zero. 

Alternatively, this script is for a (unknown to me) extended shell for which test is internal and extended for such complex constructions. (Is your ksh a specific extended version?)

2

It's meaningless.

That's the way ksh93 handle if there're too many arguments for an unary operator and the unary operator start with -, then the second one will be pick as the argument and the rest will be ignored:

$ ksh -c '[ -f a.out foo bar ] && echo yes' yes $ ksh -c '[ -e a.out foo a ] && echo yes' yes 

(Except when the second argument is -a/-o, it won't be ignored)

Checking the source of ksh93 test confirm that behavior.

Also doing strace:

$ { strace -p "$$" & sleep 1; [ -f a.out -size +0 ]; kill "$!"; } [1] 18467 Process 18455 attached restart_syscall(<... resuming interrupted call ...>) = 0 stat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("a.out", {st_mode=S_IFREG|0755, st_size=8320, ...}) = 0 kill(18467, SIGTERMProcess 18455 detached <detached ...> 

Other Bourne-like shells will report the error with this case. The behavior is unspecified by POSIX.


If you want to check whether a file exist and have size greater than 0, then standard shells have -s test operator:

[ -s file ] && echo 'file exist and size greater than 0' 

ksh88 also behave the same. With my Solaris 10 VM:

$ ksh -c '[ -f a.out foo bar ] && echo yes' yes $ strings /usr/bin/ksh | grep -i version @(#)Version M-11/16/88i 

Pre-POSIX shells also behave like that, include Bourne shell in Solaris 10, the heirloom Bourne shell, Schily osh and Schily sh.

6
  • Note that [ -s file ] is not the same as [ -f file ] && [ -s file ] as [ -s file ] doesn't check that file is a regular file (after symlink resolution). Commented Mar 1, 2016 at 12:18
  • 1
    Technically, it's not a bug in that there's nothing in the ksh documentation or POSIX test specification that says that an error should be reported in that case (or any other behaviour). It could be seen as a feature in that [ -e ./*.txt ] would check that the first file resulting from the glob expansion exists which would be a quick way to check that a glob matches (if we ignore problems with broken links). Commented Mar 1, 2016 at 12:21
  • Also note that if the 2nd argument after -f is -o or -a (binary or/and), it won't be ignored. Commented Mar 1, 2016 at 12:23
  • @StéphaneChazelas: Ah, right, the spec said the result is unspecified with this case. Commented Mar 1, 2016 at 12:27
  • @StéphaneChazelas: Do you think that behavior inherit from Bourne shell? Commented Mar 1, 2016 at 12:32

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.