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 $? 1OK,
/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 $? 0Huh? 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. /usr/bin/test
is shell-specific as well!$ 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 $? 0And 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