Сценарий - в Outlook 2011 открываю приатаченный к письму файл
Изображение открывается в Preview. Посмотрел, убедился, что всё в порядке и нажимаю “Save As…” для сохранения его в нужный мне каталог, например, в ~/Downloads. К удивлению получаю сообщение “No permission”:
У меня уже возникла мысль о том, что SSD накрывается. Нужно разобраться, что происходит.
Пожалуй, применю dtruss. Смотрю название бинарного файла Preview.app:
$ ps ax | grep Previe 1794 ?? S 0:16.37 /Applications/Preview.app/Contents/MacOS/Preview -psn_0_598162
Найденный “Preview” подставляю в dtruss:
$ sudo dtruss -n Preview -f
Повторяю попытку сохранения. Для того, чтобы очистить историю в терминале (так проще искать), нажимаю Cmd+K (Clear Scrollback). Получаю снова ошибку “You don’t have permission”, прерываю dtruss, медитирую на логи. Процесс очень короткий в отличие от многих других случаев.
Что делает Preview.app при попытке записи?
1. getattrlist("/Users/ctrld/Downloads/Image001[3].jpg\0", 0x7FFF5FBFDB30, 0x7FFF5FBFD760) = -1 Err#2 2. getattrlist("/Users/ctrld/Downloads\0", 0x7FFF5FBFDB30, 0x7FFF5FBFD760) = 0 0 3. mkdir("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview)\0", 0x1FF, 0x100864680) = -1 Err#17 4. mkdir("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 2)\0", 0x1FF, 0x100864698) = -1 Err#17 5. mkdir("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 3)\0", 0x1FF, 0x1008646B0) = 0 0 6. lstat64("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 3)/Image001[3].jpg\0", 0x7FFF5FBFE310, 0x1F8100) = -1 Err#2 7. rename("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 2)/Image001[3].jpg\0", "/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 3)/Image001[3].jpg\0") = -1 Err#1 8. lstat64("/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 3)/Image001[3].jpg\0", 0x118468948, 0x0) = -1 Err#2
Отступление. Как распознать код ошибки? Нужно посмотреть /usr/include/sys/errno.h.
$ grep 2 /usr/include/sys/errno.h
Err#2 = ENOENT = “No such file or directory”, Err#17 = EEXIST = “File exists”, Err#1 = EPERM = “Operation not permitted”.
Можно ещё посмотреть секцию ERRORS в “man getattrlist”, но там указаны имена констант, а не коды. Сами же коды - в errno.h.
- Есть ли файл Image001[3].jpg в указанном для записи каталоге? Нет (ENOENT), продолжаем.
- А каталог, куда мы указали записать файл существует? Да (0).
- Есть ли во временном каталоге подкаталог “(A Document Being Saved By Preview)”, куда можно писать временный файл (проверяем созданием этого каталога)? Есть (EEXIST).
- Добавляем единицу к индексу. Есть ли “(A Document Being Saved By Preview 2)”? Да, есть (EEXIST).
- Добавляем единицу к индексу. Есть ли “(A Document Being Saved By Preview 3)”? Не было, но уже есть.
- Есть ли файл Image001[3].jpg в нашем последнем временном каталоге? Нет (ENOENT)
- Перемещаем Image001[3].jpg из “(A Document Being Saved By Preview 2)” в “(A Document Being Saved By Preview 3)”. Доступ запрещён (EPERM)
Так, проблема в “/private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/(A Document Being Saved By Preview 2)/Image001[3].jpg”. Смотрю, почему его нельзя переместить.
$ cd /private/var/folders/X4/X4vtQdxYFpOj0O2ozpm4Wk+++TI/TemporaryItems/ $ ls -al "(A Document Being Saved By Preview 2)/Image001[3].jpg" -rw-r--r--@ 1 ctrld staff 928886 Mar 24 17:10 (A Document Being Saved By Preview 2)/Image001[3].jpg
Права доступа верны, значит нужно сразу проверять флаги (ключ - буква “O”, а не “ноль”):
$ ls -alO "(A Document Being Saved By Preview 2)/Image001[3].jpg" -rw-r--r--@ 1 ctrld staff uchg 928886 Mar 24 17:10 (A Document Being Saved By Preview 2)/Image001[3].jpg
Понятно, стоит флаг uchg (user immutable flag), не дающий ничего сделать с файлом.
Хммм… Preview такие флаги не ставит. Аттачменты, открываемые во внешних программах, сохраняются в каталоге “~/Library/Caches/TemporaryItems/Outlook Temp”. Как определил? При “Save As…” в Preview щёлкнул с Cmd на заголовок окна и увидел путь:
$ cd ~/Library/Caches/TemporaryItems/Outlook Temp $ ls -alO drwxr-xr-x@ 6 ctrld staff - 204 Mar 24 17:36 . drwx------@ 4 ctrld staff - 136 Mar 24 16:42 .. -rw-r--r--@ 1 ctrld staff uchg 766895 Mar 23 10:37 Image001.jpg -rw-r--r--@ 1 ctrld staff - 766895 Mar 23 10:39 Image001[1].jpg -rw-r--r--@ 1 ctrld staff uchg 928886 Mar 24 16:31 Image001[2].jpg -rw-r--r--@ 1 ctrld staff uchg 928886 Mar 24 17:01 Image001[3].jpg
Хм… Почему три файла с uchg? Удаляю эти аттрибуты:
$ chflags nouchg Image001*
Открываю снова приатаченный файл из Outlook и вижу снова флаг uchg в новом файле:
$ ls -alO drwxr-xr-x@ 7 ctrld staff - 238 Mar 24 17:45 . drwx------@ 4 ctrld staff - 136 Mar 24 16:42 .. -rw-r--r--@ 1 ctrld staff - 766895 Mar 23 10:37 Image001.jpg -rw-r--r--@ 1 ctrld staff - 766895 Mar 23 10:39 Image001[1].jpg -rw-r--r--@ 1 ctrld staff - 928886 Mar 24 16:31 Image001[2].jpg -rw-r--r--@ 1 ctrld staff - 928886 Mar 24 17:01 Image001[3].jpg -rw-r--r--@ 1 ctrld staff uchg 928886 Mar 24 17:45 Image001[4].jpg
Глюк Outlook? Выхожу из Outlook, удаляю файлы, захожу в Outlook, открываю приатаченный файл в Preview, снова uchg:
drwxr-xr-x@ 3 ctrld staff - 102 Mar 24 17:48 . drwx------@ 4 ctrld staff - 136 Mar 24 16:42 .. -rw-r--r--@ 1 ctrld staff uchg 928886 Mar 24 17:48 Image001.jpg
Выхожу из Outlook - временные файлы удалились. Начинаю понимать. Чтобы подтвердить догадку, захожу в Outlook, открываю приатаченный файл в Preview.app, выхожу из Outlook. Файл остаётся на месте и он уже без флага uchg:
$ ls -al drwxr-xr-x@ 3 ctrld staff 102 Mar 24 17:50 . drwx------@ 4 ctrld staff 136 Mar 24 16:42 .. -rw-r--r--@ 1 ctrld staff 928886 Mar 24 17:49 Image001.jpg
Делаю в Preview.app “Save As…”. И всё работает, ошибки по правам доступа нет!
Итак, логика Outlook становится понятной - он не даёт изменять файлы, открытые из него. Но делает это неправильно, не давая сохранить даже копию файла. Что можно сказать… Бывает…
Workaround: если вы хотите поработать с приатаченным к письму файлом, то выйдите предварительно из Outlook.
Вот пример обычного и рутинного исследования странного поведения. Вот так я и разбираюсь с проблемами - будь то сбой программы или же странная работа сервера или непонятное поведение сети.