Skip to content

test -w

Learn something new every day: I'm trying to test if a directory on a different filesystem is writable. Instead of really writing to it (e.g. by using touch(1)), I wanted to test with -w:
$ ls -ld /mnt/usb/foo
drwx------ 13 root root 4096 Jan  1 15:38 /mnt/usb/foo

$ [ -w /mnt/usb/foo ]; echo $?
1
OK, /mnt/usb/foo is not writable, because /mnt/usb was mounted read-only at this point. But look what dash(1) thinks of this:
$ [ -w /mnt/usb/foo ]; echo $?
0
Huh? But the manpage explains:
-w file  True if file exists and is writable. True indicates only that the write flag is on.
         The file is not writable on a read-only file system even if this test indicates true.
...whereas bash(1) only states:
-w file  True if file exists and is writable.
Zsh and ksh93 behave just as bash - that is returning 1 when the file is not writable, even though its permissions would allow for writes. Note that /usr/bin/test is shell-specific as well! -- Not anymore? Let's try again:
$ mount | grep /mnt
/dev/loop0 on /mnt type ext2 (rw,relatime,block_validity,barrier,user_xattr,acl)

$ bash -c "[ -w /mnt ]"; echo $?
0

$ dash -c "[ -w /mnt ]"; echo $?
0

$ bash -c "/usr/bin/test -w /mnt"; echo $?
0

$ dash -c "/usr/bin/test -w /mnt"; echo $?
0
And now for the read-only mount:
$ mount | grep /mnt
/dev/loop0 on /mnt type ext2 (ro,relatime,block_validity,barrier,user_xattr,acl)

$ bash -c "[ -w /mnt ]"; echo $?
1

$ dash -c "[ -w /mnt ]"; echo $?
1

$ bash -c "/usr/bin/test -w /mnt"; echo $?
1

$ dash -c "/usr/bin/test -w /mnt"; echo $?
1

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

Add Comment

E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
Form options

Submitted comments will be subject to moderation before being displayed.