Я пытаюсь передать дату в файл, например:
/pwd # date > file.txt
но каждый раз, когда я проверяю файл, там ничего не печатается. Я пробовал и другие варианты, например:
/pwd # echo "$(date)" > file.txt
/pwd # echo "$(/bin/date)" > /full/path/file.txt
/pwd # echo "$(/bin/date)" >> /full/path/file.txt (я не ожидал, что добавление будет иметь значение, но все равно попробовал)
Я подумал, что, может быть, это какая-то проблема с разрешениями из-за того, что date может получить доступ к файлу, поэтому, для удовольствия, я попробовал:
/pwd # sudo date > /full/path/file.txt
Попытка сохранить дату в переменной bash также бесполезна. Но, конечно же, команда date сама по себе продолжает работать:
Mon Apr 5 14:16:26 UTC 2021
У кого-нибудь есть идеи, что может происходить? Согласно всем остальным сообщениям, которые я прочитал, то, что я пытаюсь сделать, должно работать.
Обратите внимание, что это специальное (проприетарное) ядро (uname -a):
Однако он построен на Debian, поэтому я ожидал, что он будет работать.
Обновлено:
type date:
date is a tracked alias for /bin/date
При добавлении к команде префикса set -x ничего интересного не происходит, кроме отслеживания, которое я вижу при запуске команды:
strace выглядит так, как будто в нем есть хорошая информация, но я не буду притворяться, что знаю, как ее интерпретировать:
Что возвращает type date? (Это сообщит нам, если ваша команда date затенена псевдонимом / function / etc). Если перед командой запустить set -x, что-нибудь интересное / удивительное?
Один из способов исключить любые специфические особенности системы - это создать Dockerfile, воспроизводящий проблему. Если проблема может быть воспроизведена только в вашей собственной системе или где-то еще, это делает ее скорее вопросом системного администрирования, а здесь они обычно не актуальны; поэтому важно выяснить, как создать минимальный воспроизводимый пример, который воспроизводит его на чужой машине.
Еще одна вещь, на которую вы можете взглянуть, - это strace date >/full/path/file.txt, чтобы получить полную информацию о выполнении. Если при таком запуске больше нет ошибки, это означает, что удаление вашей оболочки из изображения было уместным - предположительно, type или set -x также покажут что-то странное, если использовать, как предложено выше.
Кстати, в sudo somecommand >outfile открытие outfile происходит передsudo происходит задолго до того, как может произойти somecommand. Таким образом, sudo вообще не меняет разрешения, доступные для операции открытия.
@CharlesDuffy Спасибо за все подсказки. Я отвечу на ваши вопросы в EDIT к исходному сообщению
Кстати, set +x отключит трассировку, которую включает set -x.
@CharlesDuffy Ответы на ваши вопросы / подсказки см. В исходном посте
по strace, мы должен видим строку типа write(1, "Mon 05 Apr 2021 04:26:59 CDT\n", 32) = 32, показывающую команду date, запрашивающую ОС выполнить запись в стандартный вывод от ее имени.
@CharlesDuffy Ты имеешь в виду, прямо перед close(3)?
... что io_submit необычен - это асинхронный системный вызов, тогда как write() синхронный. Мне действительно любопытно, как скомпилирован ваш glibc, чтобы использовать инструменты асинхронного ввода-вывода даже для синхронной записи.
Нет, не раньше close(3) - это чтение /etc/localtime, это совершенно нормально.
Что это за архитектура?
@CharlesDuffy uname -a указывает на armv4tl
... кстати, в общем, текстовые расшифровки здесь предпочтительнее изображений.
что выводит id -a; ls -ld .; ls -l file.txt; rm -f file.txt; ls -l file.txt; touch file.txt; ls -l file.txt?
@CharlesDuffy Я бы хотел, но у меня нет возможности копирования / вставки для моего клиента (я получаю удаленный доступ к машине)
Итак, если бы я собирался вникнуть в это, я бы изучил поведение локальной библиотеки libc, чтобы понять, почему она пытается использовать системные вызовы асинхронного ввода-вывода; но я бы хотел получить доступ к фактическим двоичным файлам, отладчику (локальному или удаленному) и системе, способной запускать их для выполнения этого расследования - это скорее оперативное расследование, чем что-то, что имеет смысл делать здесь.
... хотя догадка - и это, конечно, никуда не денется - отличается ли поведение от небуферизованного stdout? Если у вас есть команда stdbuf, ведет ли себя stdbuf -o0 date по-другому?
@jhnc Pleese см. РЕДАКТИРОВАТЬ 2 в исходном сообщении
Кстати, «отслеживаемый псевдоним» - это терминология ksh; это не должно быть помечено или названо как bash, если вы используете ksh (не то чтобы это будет иметь какое-либо значение, оболочка и date находятся на двух разных сторонах границы execve, поэтому date, как правило, ведет себя одинаково, независимо от того, какая оболочка его вызывает)
@CharlesDuffy /bin/sh: stdbuf: not found (при условии, что вы правильно поняли ваши инструкции). Поэтому я подумал, что, возможно, я не в bash (и что это был источник моей проблемы), поэтому я создал файл sh с bash shebang для выполнения моих команд, но получил тот же результат
@CharlesDuffy, как вы думаете, есть ли обходные пути? Мне буквально просто нужно передать дату / время в файл - мне все равно, как это было достигнуто
stdbuf является частью современных GNU coreutils, но в более старых системах его не будет, а в системах, использующих альтернативный набор инструментов, таких как busybox, он может быть, а может и не быть.
Если у вас делать более новая версия bash, она имеет встроенную функциональность, эквивалентную нынешней, которую вы можете использовать вместо нее.
@CharlesDuffy Извините, не могли бы вы объяснить применение вашего последнего комментария?
с тех пор ... может быть, bash 4.3 или около того? ... е / е, вы должны иметь возможность запускать printf '%(%c)T' -1 >outfile. Но вам нужно запускать это с помощью bash, а не sh, и это должна быть довольно современная версия bash.
... вы можете запустить bash и запустить echo "$BASH_VERSION", чтобы узнать, какая у вас версия.
@CharlesDuffy версия bash: 3.1.17 (1) -релиз
все выглядит нормально. один последний тест, который я забыл: echo hello > file.txt; ls -l file.txt; od -c file.txt
3.1.17 много (более десяти лет) слишком стар, чтобы иметь printf %()T. У меня нет для вас обходного пути.
Я не думаю, что у вас установлен expect? Если это так, unbuffer date подделает TTY и может заставить программное обеспечение вести себя так же, как при записи на терминал, когда stdout направлен в нетерминальный пункт назначения.
@jhnc см. последнее изображение в исходном сообщении
@CharlesDuffy В любом случае спасибо за вашу помощь - нет, у меня нет expect
Сейчас из любопытства: не возражаете, если я спрошу, что это за оборудование? Обычно я не вижу вопросов о встроенных системах 10-летней давности (предположительно) с ядрами почти 15-летней давности.
@CharlesDuffy docs.embeddedarm.com/TS-7390
ну, это определенно кажется специфическим для команды date, а не общей проблемой разрешения. Я полагаю, делать это безразлично: /bin/date > file.txt?
@jhnc это правильно
armv4t поддерживается в buildroot. Если бы я хотел создать современный программный стек для этого оборудования, я бы, вероятно, начал с него.
@jhnc, ... использование асинхронного ввода-вывода кажется мне больным - если вы посмотрите на strace, date ничего не делает для того, чтобы действительно убедиться, что запись завершена до того, как она завершится. Я с трудом воспринимаю это как что-то, кроме ошибки libc, предполагая, что это тот же GNU date, который используют все остальные, а не скрипучая сборка busybox или что-то подобное (что, вероятно, стоит проверить).
@SterlingButters, ... в этом последнем пункте, date --version дает вам номер версии или ошибку использования? В последнем случае это, вероятно, реализация, отличная от GNU.
@SterlingButters, ... Кроме того, на этом этапе, если создание полностью нового образа программного обеспечения несовместимо с работой, которую вы пытаетесь выполнить, я бы начал искать другие инструменты, доступные в системе. У вас есть интерпретатор Python? Достаточно просто, чтобы указать дату, и таким образом, если вам нужно добавить логику (например, явный сброс) для обхода странности ОС и libc, вы можете это сделать.
@CharlesDuffy Да, у меня date: invalid option -- v, а питона нет. Это ядро невероятно свернуто
@CharlesDuffy Вау ... Но у меня есть Perl
Здесь нам вредит не ядро, а минимальная пользовательская среда - мы не имеем дела с функциональностью ядра (ну, системные вызовы есть, но пользовательская среда решает, какие из них использовать и как их использовать).
... но да, думаю, пора написать на perl (тьфу, больно даже это говорить).
@CharlesDuffy LOL да, я коснулся Perl только один раз - кратко ... ОЧЕНЬ кратко. Я могу попросить производителя, чтобы они тоже рассмотрели этот вопрос, но я все равно ценю вашу помощь.
Они все еще поставляют и поддерживают этот программный стек сегодня? Это страшно - это десятилетие обновлений безопасности, которых нет.
В прошлой жизни я работал на компания, которая создала и поддерживала дистрибутив Linux специально для встраиваемых систем. Есть веские причины, по которым стоит платить за наличие постоянно обновляемого и активно поддерживаемого стека программного обеспечения. :)
perl -e '$|=1; print scalar localtime, "\n"' > file.txt@jhnc Это работает! Спасибо! Вы и Чарльз должны поделиться принятым ответом
@CharlesDuffy, я так полагаю - или продавец сидел на оборудовании вечно, пока оно действительно не использовалось ... Но я согласен - не идеально
Ссылка @CharlesDuffy говорит о Standard Linux utilities are provided by the busybox program. Type 'help' for a list of provided utilities. Source code for the busybox utility is available on the Technologic Systems FTP site. , поэтому, вероятно, можно точно выяснить, что происходит, если версия известна, проверив источник (или files.embeddedarm.com/ts-arm-sbc/ts-7390-linux/sources)





Это необычная ситуация - по результатам strace это похоже либо на ошибку libc, либо на проблему с busybox. Поскольку это программный стек десятилетней давности, у вас нет недавно представленного встроенного bash форматирования даты printf, добавленного в 4.3.
Самый простой обходной путь - вообще не использовать команду busybox date, а вместо этого переключиться на язык сценариев - Python, Perl и т. д. @jhnc был достаточно любезен, чтобы предоставить команду perl для этой цели:
perl -e '$|=1; print scalar localtime, "\n"' > file.txt
У меня отлично работает под
Linux nkclintjs 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux(CentOS 7)