Shek Script mktemp, який найкращий метод для створення тимчасової названої труби?


30

Я знаю, що найкраще створювати тимчасові файли за допомогою mktemp, але як бути з іменованими трубами?

Я вважаю за краще, щоб речі були максимально сумісними з POSIX, але прийнятний лише Linux. Уникнення башизмів - мій єдиний жорсткий критерій, про який я пишу dash.

Відповіді:


41
tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"

На відміну від звичайного створення файлів, який схильний до викрадення наявним файлом або символічним посиланням, створення імені каналу через mkfifoабо основної функції або створює новий файл у вказаному місці, або не працює. Щось подібне : >fooнебезпечно, тому що якщо зловмисник може передбачити вихід, mktempтоді зловмисник може створити цільовий файл для себе. Але mkfifo fooне вдалося б за такого сценарію.

Якщо вам потрібна повна портативність POSIX, mkfifo -m 600 /tmp/myfifoвона безпечна проти викрадення, але схильна до відмови в обслуговуванні; без доступу до сильного генератора випадкових імен файлів, вам потрібно буде керувати спробами повторних спроб.

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

tmpdir=
cleanup () {
  if [ -n "$tmpdir" ] ; then rm -rf "$tmpdir"; fi
  if [ -n "$1" ]; then kill -$1 $$; fi
}
tmpdir=$(mktemp -d)
trap 'cleanup' EXIT
trap 'cleanup HUP' HUP
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
mkfifo "$tmpdir/pipe"

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

1
Чи не повинна бути команда пастки trap "rm -rf '$tempdir'" EXIT HUP INT TERM? Чи може пастка зробити це власне змінне розширення?
Шість

@Six Ваша команда розшириться $tempdirпід час оцінки trapкоманди, а не в момент запуску пастки. У цьому випадку це не має ніякої різниці, за винятком того, що ваш код жахливо розбивається, якщо значення tempdirмістить одну цитату, тоді як мій код завжди працює.
Жиль "ТАК - перестань бути злим"

@Gilles Це приємна особливість. Я без спроби спробував ваш єдиний приклад цитати, тому я подумав, що пастка не може оцінити змінні під час виконання. Виявилося, що моє $tempdirбуло оголошено локально, і його потрібно визначити глобально, щоб пастка мала доступ до нього. Має сенс зараз ...
Шість

1
@Gilles ... до тих пір, поки $tempdir значення також не зміниться, що прийнятно для всіх цілей. Будьте обережні, щоб не використовувати одне ім’я для створення декількох тимчасових файлів / dirs ...
MestreLion

3

Більш безпечною альтернативою є безпечне mktempстворення каталогу, а потім помістити названу трубу всередину цього каталогу, зробити це, rm -R $dirщоб в кінці кінців позбутися.


Я вирішив створити FIFO в mktempкаталозі, оскільки це був єдино прийнятний відповідь. Про всяк випадок, якщо ви цього не помітили, @Gilles вже опублікував цю відповідь поглиблено.
Дж. М. Бекер

2

Скористайтеся опцією "сухий пробіг":

mkfifo $(mktemp -ut pipe.XXX)

1
За даними сторінок man, використання -uопції "не рекомендується".
собачка

@dogbane Так це використання -t, але поки це надійно працює, я б пішов з ним.
полемон

Вибачте, де це говорить, що -tце не відлякує?
собачка

2
@dogbane Якщо якимось чином це критично, я б зробив крихітний додаток C, викликавши mkstemp()функцію ( linux.die.net/man/3/mkstemp ). -tВимикач не рекомендується, це -p, мій поганий.
полемон

1

Ви можете використовувати mktempдля створення тимчасового файлу, а потім видалити його та створити названу трубку з тим же ім’ям.

Наприклад:

TMPPIPE=$(mktemp -t pipe.XXX) && {
    rm -f $TMPPIPE
    mkfifo $TMPPIPE
}

Чи видаляється $TMPPIPEпопередня, щоб mkfifoуникнути проблеми, пов'язаної з небезпекою TMPPIPE=`mktemp -u` ; mkfifo $TMPPIPE?
Дж. М. Бекер

1
@TechZilla mkfifoнасправді безпечний, на відміну від звичайного регулярного створення файлів з оболонки. Якщо це не так, створення файлу, то видалення його зовсім не допоможе (адже це значно полегшить роботу нападника, не вимагаючи від нього вгадати ім'я файлу). Так відповідь dogbane працює, але проміжне створення файлів є марним ускладненням.
Жил "ТАК - перестань бути злим"

1
@Gilles, чи знаєш ти, в чому відношенні mktempсторінка man назвала -uпараметр "небезпечним"?
Дж. М. Бекер

@dogbane, я проголосував за вашу відповідь, і ваші коментарі, які я вважав, були твердими. Хоча, я це вже завершив вчора .. Я просто чекав, коли хтось опублікує або моє рішення, або, сподіваюся, краще. Тож хоч я і використовував mktemp -dвас, ви все-таки отримали кілька балів для вашого внеску. Дякую за всю вашу допомогу, я дуже це вдячний!
Дж. М. Бекер

1
@TechZilla mktemp -uнебезпечний при створенні звичайного файлу, оскільки він забезпечує захист від відмови у наданні сервісу (якщо ім'я, яке він створює, є досить непередбачуваним), але не заважає зловмиснику створювати файл під носом програми. Створення файлу замість звичайного файлу є рідкісним випадком використання, на якому man page не звертається.
Жил "ТАК - перестань бути злим"

0

Використовуйте mkfifoабо mknodв Unix, де за двома окремими процесами можна отримати доступ до труби по імені - один процес може відкрити її як читач, а другий - як письменник.

mkfifo my_pipe
gzip -9 -c < my_pipe > out.gz
cat file > my_pipe

Названу трубку можна видалити так само, як і будь-який файл:

rm my_pipe

mkfifo --mode=0666 /tmp/namedPipe
gzip --stdout -d file.gz > /tmp/namedPipe

NamedPipe може використовувати звичайний файл для читання лише один раз.

http://www.linuxjournal.com/article/2156


2
Я повністю знаю про названі труби та mkfifo. Він не стосується мого питання про тимчасові названі труби, більше ніж mkdirстосується створення тимчасових каталогів.
Дж. М. Бекер

2
Як це вирішує проблеми, які mktempстосуються безпечного створення названої труби?
camh

1
Ой добре, найкраще створити їх під / tmp, вони є тимчасовими файлами за визначенням і очистяться, як тільки система перезавантажиться. Або ще краще, мати функцію оболонки, яка створить ідентифіковану трубу з самого mktempрезультату (звичайно, спочатку видаливши тимчасовий файл, а потім виконавши mkfifoтой самий). mktempможна також використовувати для створення тимчасового каталогу, спробуйте -t -dпереключитися.
Nikhil Mulley
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.