Как уже говорили другие, ваши если тест...; fi
операторы синтаксически неверны, но также стоит отметить, что весь ваш подход немного грубый. Есть пара областей, в которых поток этого сценария может быть резко улучшен - в частности, в том, что его будет легче читать и редактировать позже.
Сначала можно задать
параметры выбора итеративно в цикле для
. В этом пути любой возможный выбор будет объявлен пользователю и автоматически сгенерирован его селектор, но в сценарии вы можете объединить их в список последовательностей, не беспокоясь ни о:
set --
for c in \
"Base install:base_fn" \
"Mintrepos:mint_fn" \
"Asusn13 driver:asus_fn" \
"Install Standard openbox:std_obox_fn" \
"Install Xfceopenbox:xfce_obox_fn" \
"backing up standard open box config:bkup_fn obox" \
"backing up openboxfce:bkup_fn xfce"
do
set -- "$@" "${c##*:}"
printf "'%s' = $#\n" "${c%:*}"
done
Это кодирует вызываемое fn _ name
в массив позиционных параметров, одновременно печатая понятное пользователю описание stdout.
После создания списка выбранных элементов в «$ @»
и печати хода выполнения, можно прочитать
выбранные пользователем элементы в небольшом цикле, который будет закрыт после слишком большого количества неудачных попыток, а также проверить их ввод:
chk=$((($#<1)*5)) #if not at least one choice quit
until [ "$((chk+=1))" -gt 5 ] && exit 1 #chks up to 5 times or quits
printf '\nSelect: ' #prompts for each try
read -r c && [ -n "${c##*[!0-9]*}" ] #fails if input not number or empty
do echo "Invalid selection."; done #prints a notice and retries
В последний раз можно просто сдвинуть
все ненужные параметры и вызвать $1
:
shift "$((c-1))"; $1
Лучше проверить, нет ли начальных нулей. shift
приведет к ошибке, если пользователь выбрал слишком большое число.
[ "$((c=$(printf %.d "$c")))" -gt 0 ] || exit
shift "$((c-1))" && $1
Это для числового списка выбора, что делает позиционный массив очень полезным. В более общем случае можно использовать оператор case
:
case "$choice" in
(pattern 1) do as necessary for a match;;
(pattern 2) do otherwise for this match;;
(pattern 3) continue this wise for each;;
(*) until there isn't a match ;;
esac
Это только переносимые средства эмуляции того, что многие оболочки (включая bash
) предложат в качестве оператора select
, введенного ksh
много лет назад.
Из man bash
:
выберите
name [ в
word ]; сделать
список ; done
«$ @»
) (см. ПАРАМЕТРЫ ниже). Появится подсказка $ PS3
и строка, считанная из стандартного ввода. -121--105558-
Другие ответы пропускают три пункта:
Никогда не делайте этого:
/usr/bin/find /var/www/cache/blah/ |xargs /bin/rm -f >/dev/null 2>&1
потому что, когда у вас есть файл с космосом в нем, rm
попытается удалить два файла, что приводит к неожиданным результатам.
Если вы настаиваете на этом пути, предполагая, что вы используете GNU find
и xargs
, вы хотите:
/usr/bin/find /var/www/cache/blah/ -print0 | xargs -0 /bin/rm -f >/dev/null 2>&1
, который обнуляет файлы (и ожидает нулевое окончание в xargs).
Во-вторых, вы пытаетесь удалить каталоги или нет? Если нет, вы хотите «-type f». Если это так, «rm -rf» как rm
без -r
не будет удалять каталог.
Но самое главное, что ОП попросила более короткий метод, и ответы кажутся более длинными. Как насчет:
/usr/bin/find /var/www/cache/blah/ -delete
Я верю -delete
является внутренним номером GNU, поэтому проверьте версию find
.
-121--66835-
scp
сам по себе не имеет такой функции. С GNU parallel
можно использовать команду sem
(из семафора ) для произвольного ограничения параллельных процессов:
sem --id scp -j 50 scp ...
Для всех процессов, запущенных с одним и тем же -id
, применяется ограничение в 50 параллельных экземпляров. Попытка запустить 51-й процесс будет ждать (неопределенно долго), пока один из других процессов не завершит работу. Добавьте --fg
, чтобы сохранить процесс на переднем плане (по умолчанию он выполняется в фоновом режиме, но не ведет себя точно так же, как фоновый процесс оболочки).
Обратите внимание, что состояние хранится в $ {HOME }/.parallel/
, поэтому это не будет работать так, как надеялись, если у вас есть несколько пользователей, использующих scp
, вам может потребоваться нижний предел для каждого пользователя. (При вызове sem
можно также переопределить переменную среды HOME
, убедиться в том, что umask
разрешает групповую запись, и изменить разрешения таким образом, чтобы они имели общее состояние, но я не тестировал это сильно, YMMV.)
parallel
требует только perl
и нескольких стандартных модулей.
Можно также использовать scp -l N
, где N - ограничение передачи в Кбит/с, выбрать определенный шифр (для скорости, в зависимости от требуемой безопасности) или отключить сжатие (особенно если данные уже сжаты), чтобы еще больше уменьшить влияние процессора.
Для scp
ssh фактически является каналом, и экземпляр scp
запускается на каждом конце (принимающий конец запускается с опцией -t
без документов). Что касается MaxSessions
, это не поможет, «сеансы» мультиплексируются по одному соединению SSH. Несмотря на обширную дезинформацию об обратном, MaxSessions
ограничивает только мультиплексирование сеансов по TCP-соединению, а не любое другое ограничение.
Модуль PAM pam _ limits
поддерживает ограничение одновременных входов в систему, поэтому, если OpenSSH построен с PAM и usePAM yes
присутствует в sshd _ config
, можно установить ограничение по имени пользователя, членству в группе (и многое другое). Затем можно установить жесткий maxlogins
для ограничения имен входа в /etc/security/limits.conf
. Однако это подсчитывает все имена входа для каждого пользователя, а не только новые имена входа, использующие только ssh
, и не только scp
, поэтому вы можете столкнуться с проблемами, если у вас нет выделенного идентификатора пользователя scp
. После включения он также будет применяться к интерактивным сеансам ssh. Один из способов - скопировать или синхронизировать двоичный файл sshd
, вызвав его sshd-scp
, затем можно использовать отдельный файл конфигурации PAM, т.е. /etc/pam.d/sshd-scp
(OpenSSH вызывает pam _ start ()
с «именем службы» набора, чтобыВам нужно будет запустить его на отдельном порте (или IP), и использование отдельного sshd _ config
, вероятно, тоже хорошая идея.
Если вы реализуете это, то scp
будет неудачным (exit code 254) при достижении лимита, поэтому вам придется иметь дело с этим в процессе переноса.
(Другие варианты включают ionice
и cpulimit
, они могут привести к тайм-ауту или зависанию сеансов scp
в течение длительных периодов времени, вызывая дополнительные проблемы.)
Старый школьный способ сделать что-то подобное заключается в использовании atd
и batch
, но это не предлагает настройки параллелизма. Более новым вариантом является диспетчер очереди задач , который поддерживает постановку в очередь и выполнение заданий более конфигурируемым последовательным/параллельным способом с поддержкой реконфигурации во время выполнения (например, изменение заданий в очереди и параметров настройки параллелизма), хотя он не обеспечивает самого управления нагрузкой или ЦП.
EDIT: (Исходный ответ по-прежнему отвечает на заданный вопрос, но действительно делает файл file.js недопустимым файлом JS). Для обеспечения требуемого поведения следует shebang + 1st-line-combination
, которая будет передавать файл .js через узел
, пропуская две первые строки, таким образом, подавая его только с кодом JS:
#!/bin/sh
sed '1,2d' $0 |node --harmony_arrow_functions; exit $?
/* Your JS code begins here */
--- Ниже исходного ответа ---
Если вы можете считать, что ваш интерпретатор будет находиться в том же каталоге интерпретируемого файла (который является заявленным вопросом), вы можете использовать $ (dirname $0)
для получения его пути.
Пример:
#!/bin/sh
exec $(dirname $0)/nodeharmony.sh "$0" "$@"
В этом случае при выполнении
$ cd ..
$ ./subfolder/file.js
$ (dirname $0)
разрешится в ./подпапка
, поэтому exec будет использовать ./подпапка/nodeharmony.sh
в качестве интерпретатора.
Когда inotifywait
выводит последовательность " Часы установлены. "является безопасным для внесения изменений в наблюдаемые inodes, поэтому перед прикосновением к файлам следует дождаться появления последовательности при стандартной ошибке.
Например, этот код должен соответствовать
inotifywait -r -m -e close_write "somedir" \
2> >(while :;do read f; [ "$f" == "Watches established." ] && break;done;\
find "somedir" -type f -exec touch {} ";")\
| while read f; do echo "$f hi";done
-121--63161- Если клиент/сервер не показывает ход выполнения - можно проверить ход отправки на стороне клиента на основе хода чтения файла.
pos: 12313 flags: 0100002
Это означает, что позиция в этом файле 12313 - так что - если вы разделяете позицию (12313) на файл - у вас есть общий прогресс.
Поведение, которое вы наблюдаете, произошедший, потому что, хотя клиент имеет письменные данные в розетку для подключения к данным FTP, и ядро клиента ответило, что это произошло успешно (вернувшись из ()
Или Отправить ()
Системный вызов), данные все еще являются во всех видах буферов и еще не привержены файлу назначения. Это в сетевых буферах в исходной ОС, он в буферах в картах Ethernet, он в полете на проводе, он в буферах в пункте назначения, он в буферах FTP-сервера, он был записан в файл на сервере, но не покраснул на диск и т. Д. ...
Это не только с ftp. Вы можете легко заметить, что это происходит с более современными инструментами передачи файлов, таких как SCP
. SCP
Файл на полпути AQRound Planet (для сети высокой задержки) или в систему с медленным хранением, и вы увидите, что прогресс передачи показан как быстрее, чем это, то, кажется, Повесьте на 100% на некоторое время, пока команда фактически завершится.
Если вы посмотрите на исходный код для Netkit-ftp (клиент по умолчанию / стандартное FTP на Debian), его обработка знаков # не делает ничего особенного. Он пишет хэш-следы в соответствии с большинством данных, которые он написал в сокет для подключения данных. Таким образом, это проявляет то же самое поведение, которое вы наблюдаете.
Какие обычные клиенты FTP делают, и то, что вы должны сделать, тоже ждут ответа на команду
команда на контрольном соединении. Этот ответ придет некоторое время после того, как вы уже покраснели и закрыли разъем подключения данных. Когда вы получаете этот ответ, вы знаете, что FTP-сервер имеет данные. Это может быть не полностью привержено на диске там, но это столько же подтверждения, поскольку вы собираетесь получить.