Як встановити конкретні дозволи для файлів під час перенаправлення виводу?


12

Це, мабуть, дублікат, але всі мої пошуки викликають запитання про помилки, відхилені у дозволі.

Я виконую команду в оболонці bash. Я хочу перенаправити вихід, щоб додати файл, який, ймовірно, не існує при першому запуску. Я хочу встановити режим дозволу на конкретні файли, якщо перенаправлення виводу має створити цей файл. Чи є спосіб це зробити за допомогою однієї команди?

Наприклад, я можу спробувати

foo >> /tmp/foo.log 0644

де 0644є дозволи, які я хочу foo.logзакінчити. Більшість команд, з якими я експериментував у bash, в кінцевому підсумку трактують 0644як додатковий аргумент foo.

У мене виникає відчуття, що це буде приймати другу команду до chmodдозволів до або після її написання.

Я використовую GNU bash 4.2.25 та Ubuntu 12.04, якщо це має значення - загальні відповіді є кращими.

Відповіді:


5

Неможливо зробити це під час прокладки труб, наскільки я знаю, простий сценарій може бути найкращим рішенням.

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi

Дякую Slowki, це теж був мій прихисток. Я збираюся залишити його відкритим на кілька днів, сподіваючись залучити гуру, щоб освітити нас.
Патрік М

3
Проблема такого підходу полягає в тому, що він створює короткий проміжок часу, коли дозволи на файл неправильні. Я б не використовував його, якщо метою є захист конфіденційних даних.
proski

1
Ця відповідь працює, наскільки це йдеться, але @proski має рацію: umaskвідповіді краще, і одну з них слід прийняти.
Скотт

15

Я знаю, що це старе питання, але я хотів додати свої два центи.

У мене була така ж ідея і я придумав рішення, схоже на BowlesCR . Проблема з його рішенням полягала в тому, що моя команда ( foo) не буде працювати, якщо я змінив umask перед його запуском, тож це мій погляд на проблему:

foo | ( umask 0033; cat >> /tmp/foo.log; )

Тут umaskвпливає лише перенаправлення на foo.logпідпакет. Все інше залишається незмінним.

Трохи заплутаний, але це працює.


Дуже приємно і ефективно :) Просто не можна використовувати з більш жорстким перенаправленням поверх stdout redir.
Orsiris de Jong

5

Без справжнього сценарію ви можете трохи ланцюжок:

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log

Ефективно схожий на відповідь Словкі , але згущений в однолінійку .

Єдине інше, що я можу придумати, - це повозитися з умаском. Найкраще робити це в нижній частині корпусу, щоб воно не забруднювало поточне середовище:

(umask 0033 && foo >> /tmp/foo.log)

Однак два питання з цим.

  1. Umask не може підняти дозволи вище рівня, визначеного в creat()syscall (як видається, Bash використовує 0666).
  2. Це не змінить дозволи на існуючий файл (оскільки umaskстосується лише створення файлів ).

Я ще достатньо новий для * nix, що умаск для мене ще трохи чарівний. Дякую за пораду, я обов’язково прочитаю її.
Патрік М

Хм ... Все ж дозволяє непривілейований процес відкрити файл і пізніше прочитати його вміст.
Feuermurmel

(1) Вітаємо, що знайшли цікаве, корисне використання cat. (Хоча це не відповідає стандартній схемі марного використання  cat.) (2) Я припускаю, що ти мав намір сказати, що під час створення файлів типово налаштовуєш режим  0666 , і тому я відредагував свою відповідь, щоб сказати це. (Дивіться це ,  це   … (Продовження)
Скотт

(Протяг)… і  це .) І питання конкретно згадує режим 0644. Значить, umaskзначення 22, 23 або 32 також буде працювати в цьому контексті (не потрібно використовувати провідні нулі); коли режими та  umaskзначення задаються чисельно, вони завжди трактуються як вісімкові).  22 частіше, умовно використовується.
Скотт

@Feuermurmel: Так що? Питання прямо вимагає режиму 644. Ми повинні припустити, що ОП знає, що 644 означає "читабельний" у всьому світі та має намір оприлюднити його інформацію.
Скотт

1

Коли перенаправлення встановлює неправильні дозволи, наприклад:

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ ls -l capture.*
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDERR
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDOUT
$ cat capture.*
215 STDERR
216 STDERR
215 STDOUT
216 STDOUT

Я вважаю, що ви можете використовувати щось на кшталт xynomorf, що дало, і вирішити більш серйозну проблему з боку Орсіріс де Йонга з невеликою модифікацією, щоб використовувати заміну процесу баш .

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ ls -l capture.*
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDERR
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDOUT
$ cat capture.*
233 STDERR text
238 STDERR text
233 STDOUT text
238 STDOUT text

Звичайно, використовуйте umask 0077для отримання режиму 600 та забороняйте іншим користувачам бачити вміст.


0

Якщо ви хочете переспрямувати на сценарій, на відміну від umaskпідстановки процесу, а також installви можете встановити біт виконання:

install -m 755 <(echo commands go here) newscript

<()поміщає вихід у тимчасовий файл, див. Процес-заміна

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.