Принудительное завершение работы Finnix (Linux Rescue Disk )без запроса извлечения компакт-диска при нажатии кнопки питания

Указание, указывает ли файловый дескриптор на терминальное устройство

Программа может определить, связан ли файловый дескриптор с tty-устройством, используяisatty()стандартную функцию C (, которая, как правило, выполняет безобидный -специфический ioctl()системный вызов tty, возвращающий сообщение ошибка, когда fd не указывает на устройство tty ).

Утилита [/ testможет сделать это с помощью своего оператора -t.

if [ -t 1 ]; then
  echo stdout is open to a terminal
fi

Отслеживание вызовов функций libc в системе GNU/Linux:

$ ltrace [ -t 1 ] | cat
[...]
isatty(1)                                      = 0
[...]

Отслеживание системных вызовов:

$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010)        = -1 ENOTTY (Inappropriate ioctl for device)
[...]

Говорит, указывает ли он на трубу

Чтобы определить, связан ли fd с каналом/fifo, можно использовать системный вызовfstat(), который возвращает структуру, поле st_modeкоторой содержит тип и разрешения файла, открытого на этом fd.. Стандартный макросS_ISFIFO()C можно использовать в этом поле st_mode, чтобы определить, является ли fd каналом/fifo.

Не существует стандартной утилиты, которая может выполнять fstat(), но есть несколько несовместимых реализаций команды stat, которые могут это делать. zshвстроенная функция statс stat -sf "$fd" +mode, которая возвращает режим в виде строкового представления, первый символ которого представляет тип(pдля канала ). GNU statможет сделать то же самое с stat -c %A - <&"$fd", но также имеет stat -c %F - <&"$fd"для сообщения только типа . С BSDstat:stat -f %St <&"$fd"или stat -f %HT <&"$fd".

Сообщить, доступен ли поиск

Приложения, как правило, не заботятся о том, является ли stdout каналом. Их может заботить возможность поиска (, хотя обычно они не решают, следует ли буферизовать или нет ).

Чтобы проверить, является ли fd доступным для поиска (каналы, сокеты, устройства tty недоступны для поиска, обычные файлы и большинство блочных устройств обычно ), можно попытаться выполнить относительныйlseek()системный вызов с смещение 0 (так безобидно ). dd— это стандартная утилита, представляющая собой интерфейс к lseek(), но ее нельзя использовать для этого теста.поскольку реализации вообще не будут вызывать lseek(), если вы запросите смещение 0.

Оболочки zshи ksh93имеют встроенные операторы поиска, хотя:

$ strace -e lseek ksh -c ': 1>#((CUR))' | cat
lseek(1, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
ksh: 1: not seekable
$ strace -e lseek zsh -c 'zmodload zsh/system; sysseek -w current -u 1 0 || syserror'
lseek(1, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
Illegal seek

Отключение буферизации

Команда scriptиспользует псевдотерминальную пару -для захвата выходных данных программы, поэтому стандартный вывод (программы, а также стандартный ввод и стандартный вывод )будут псевдотерминалом -.

Когда стандартный вывод направляется на терминальное устройство, как правило, сохраняется некоторая буферизация, но она построчная. printf/ putsи co не будут ничего писать до тех пор, пока не будет выведен символ новой строки. Для других типов файлов буферизация осуществляется блоками (по несколько килобайт ).

Существует несколько вариантов отключения буферизации, которые обсуждаются в нескольких вопросах и ответах здесь (поиск unbuffer или stdbuf , Не удается перенаправить вывод дает несколько подходов )либо с использованием псевдотерминала -, как это можно сделать с помощью socat/ script/ expect/unbuffer(скрипта expect)/ zshzptyили внедрив код в исполняемый файл для отключения буферизации, как это делается в GNU или FreeBSD stdbuf.

1
16.04.2021, 14:46
1 ответ

Я попробовал несколько методов, таких как использование rc6.dили rc0.d, но все они не работают. Затем я нашел этот полезный пост о том, как запустить скрипт прямо перед завершением работы. Моя цель - переопределить команду выключения, которая запускается наshutdown -f

В сообщении меня попросили создать скрипт в /usr/lib/systemd/system-shutdown. Когда я перехожу в этот каталог, я нахожу скрипт с именем live-tools.shutdown. Файл содержит следующий код:

#!/bin/bash
/bin/live-medium-eject

Итак, я прочитал другой файл /bin/live-medium-ejectи обнаружил, что в этом файле есть код для ожидания ввода пользователем (нажмите Enter, чтобы извлечь диск ). Так что мне просто нужно прокомментировать такой код:

#!/bin/bash
#/bin/live-medium-eject

После этого при использовании кнопки питания не будет запрашиваться извлечение диска. Решено.

Другой способ, который я могу придумать, не нарушая код, состоит в том, чтобы создать новый сценарий внутри /usr/lib/systemd/system-shutdownс именем что-то вродеareboot(с первым символом a, чтобы он мог выполняться первым )и внутри этого сценария я можно поместить этот код и сделать его исполняемым:

#!/bin/bash
reboot -f

Я думаю, что это сработает, но я не проверял это. Первый работает, но я не уверен, нужен ли скрипт другим после того, как я его отключил.

1
28.04.2021, 22:52

Теги

Похожие вопросы