В общем, это невозможно, как объяснялось в нескольких других ответах.
Однако оболочки Unix являются обычными программами (, и они интерпретируют командную строку и подставляют ее, то есть расширяют команду перед выполнением fork
и execve
для нее ). См. это объяснение bash
операций оболочки . Вы можете написать свою собственную оболочку(или исправить некоторые существующие свободные программы , например. GNU bash)и использовать его в качестве оболочки (или даже оболочки входа в систему, см. passwd (5)и оболочки (5)).
Например, у вас может быть ваша собственная программа-оболочка, поместившая полную командную строку в какую-нибудь переменную окружения (представьте себе MY_COMMAND_LINE
например)-или используйте любой другой вид inter -связь процесса для передачи командной строки из оболочки в дочерний процесс -.
Я не понимаю, зачем вам это нужно, но вы можете запрограммировать оболочку, ведущую себя таким образом (, но я не рекомендую этого делать ).
Кстати, программа может быть запущена некоторой программой, которая не оболочка (, но которая выполняет fork (2 ), затем execve (2 ),или просто execve
для запуска программы в ее текущем процессе ). В таком случае вообще нет командной строки, и ваша программа может быть запущена без команды...
Обратите внимание, что у вас может быть (специализированная )система Linux без установленной оболочки. Это странно и необычно, но возможно. Затем вам нужно будет написать специализированную программу инициализации , запускающую другие программы по мере необходимости -без использования какой-либо оболочки, но с помощью fork
и execve
системных вызовов.
Читайте такжеОперационные системы :Три простых элементаи не забывайте, что execve
практически всегда является системным вызовом(в Linux, они перечислены в системные вызовы (2 ), см. также введение (2 )), которые повторно инициализируют виртуальное адресное пространство(и некоторые другие вещи )процесса делаю это.
Вы можете использовать цикл while -, который зацикливается навсегда, и break
цикл, если файл не найден. Вам нужно переместить команду find
внутрь цикла для повторных проверок:
#!/bin/bash
while true; do
logfile=$(find /home -maxdepth 1 -type f -mmin -1 -name 'test.log')
if [ -z "$logfile" ]; then
break # no file found, break while-loop
fi
echo "Now sleeping for 20 seconds"
sleep 20
done
echo "Job is finished"
FILE=$(find. -maxdepth 1 -type f -mmin -1 -name 'test.log' | wc -l)
Подстановка команд расширяется и find
запускается прямо здесь, когда выполняется назначение. Вы не меняете FILE
больше нигде, поэтому он сохранит значение, полученное в начале скрипта. Переместите подстановку и присваивание команд внутрь цикла.
Вы не изменяете переменную FILE
внутри цикла (, поэтому она остается неизменной ), и поэтому либо завершается немедленно, либо входит в бесконечный цикл.
Если в вашей системе Linux есть команда stat
, попробуйте
while (( ( $(printf "%(%s)T") - $(stat -c"%Y" test.log) ) < 60 ))
do echo "Now sleeping for 20 seconds"
sleep 20
done
Он использует функции bash
%()T
и ((...))
и формат эпохи stat
для простого вычитания двух значений времени. Если файл изменяется в течение минуты, он продолжает повторяться, пока файл не станет старше одной минуты.
Небольшая перегонка раствора @Freddy:
#!/bin/bash
while find /home -maxdepth 1 -type f -mmin -1 -name 'test.log' | grep -q.
do
echo "Now sleeping for 20 seconds"
sleep 20
done
echo "Job is finished"
В этом решении используется переключатель grep
's -q
для подавления обычного вывода команды grep, который просто проверяет вывод find
на пустое/не пустое состояние. Цикл while
будет продолжаться до тех пор, пока команда find
выводит хотя бы одну строку текста. Как только файл test.log
старше одной минуты, find
больше не производит никакого вывода, и команда grep
завершается с ошибкой, что приводит к прекращению цикла.