Я уже сталкивался с этим раньше. Похоже, что некоторые беспроводные карты не очень хорошо работают с 802.11n на *nix. Ответ (если это действительно ваша проблема), как объясняется здесь, например, заключается в полном отключении 802.11n:
echo "options iwlagn 11n_disable=1" | sudo tee /etc/modprobe.d/iwlagn.conf
sudo modprobe -rf iwlagn
sudo modprobe -v iwlagn
Чтобы узнать тип вашей беспроводной карты:
lspci | grep -i ethernet
В этом скрипте есть несколько неправильных вещей, которые можно улучшить.
Основная проблема в вопросе, по-видимому, заключается в том, почему два вызова echo
не производят никакого вывода.
Когда вы используете подстановку команд, как в
echo `rm file`
или эквивалент
echo $(rm file)
, то echo
получит вывод команды внутри обратных кавычек или внутри $(...)
. Ни одна из ваших замен команд не производит никакого вывода. Обе команды, которые вы используете в обратных кавычках, изменяют файлы, но опять же, ни одна из них не производит вывод в свой стандартный поток вывода (, который обычно отображается в терминале ). Это означает, что оба вызова echo
также не дадут никаких результатов, за исключением пустой строки.
В целом, echo $(...)
является анти-паттерном -, то есть вы можете делать то же самое гораздо лучше.
Если вы действительно хотите вывести результат какого-то конвейера pipeline
, то вместо записи
echo $(pipeline)
вы бы сказали просто
pipeline
Будет отображаться вывод pipeline
, так как вывод команд обычно отображается в терминале.
В приведенном ниже коде я вставил пару операторов printf
, которые будут выводить соответствующую «информацию о ходе выполнения» в сценарии (s ).
Вот модифицированная версия скрипта, которая полностью не проверена (, так как у меня нет доступа к используемым вами инструментам или входным файлам ), но он должен имитировать то, что ваш скрипт делает, в том числе создает эти промежуточные файлы (они не нужны, а как от них избавиться я покажу позже ).
#!/bin/bash
export LD_LIBRARY_PATH="/usr/lib/fsl/5.0:$LD_LIBRARY_PATH"
timefmt="%C --- CPU:\t%E real,\t%U user,\t%S sys\t%P\tMem:\t%KkiB avg.,\t%MkiB max.\tExit:\t%x"
for dirpath in /input/sub-*/; do
name=$(basename "$dirpath")
id=${name#sub-}
printf '%s\n' "$id"
printf 'Found ID: %s\n' "$id" >&2
done | split -l 8 - participants_
for participants_id in participants_*; do
ids=( $(<"$participants_id") )
printf 'Processing ID: %s\n' "${ids[@]}" >&2
/usr/bin/time -f "$timefmt" \
fmriprep /input /output participant \
--fs-license-file /opt/freesurfer/license.txt \
--fs-no-reconall --use-aroma \
--ignore fieldmaps --n_cpus 12 --force-bbr \
--participant_label "${ids[@]}" \
-w /output
rm -f "$participants_id"
done
Исправления:
Команда time
не обязательно должна быть псевдонимом только из-за наличия длинного аргумента опции для ее опции -f
. Псевдонимы в любом случае не раскрываются в сценариях. Я просто сохраняю аргумент в строке и использую ее при вызове time
.
Ваш цикл добавляется к LD_LIBRARY_PATH
в на каждой итерации. В этом не было необходимости.
Получение идентификаторов из имен каталогов лучше выполнять в соответствующем цикле. Этот цикл исчезнет позже, когда вместо этого мы будем использовать массив для хранения идентификаторов.
Вместо того, чтобы использовать find
для поиска промежуточных файлов, мы просто используем их с простым шаблоном подстановки имен файлов. Мы знаем, что они здесь и как их зовут.
Только что обработанный промежуточный файл удаляется внутри цикла.
Код делается читаемым за счет использования продолжений строк.
Вызов wait
удален. Никаких фоновых задач ждать не приходится.
В следующем варианте идентификаторы хранятся в массиве all_ids
вместо временных файлов:
#!/bin/bash
export LD_LIBRARY_PATH="/usr/lib/fsl/5.0:$LD_LIBRARY_PATH"
timefmt="%C --- CPU:\t%E real,\t%U user,\t%S sys\t%P\tMem:\t%KkiB avg.,\t%MkiB max.\tExit:\t%x"
all_ids=( /input/sub-*/ )
all_ids=( "${all_ids[@]#/input/sub-}" ) # remove "/input/sub-" from each item
all_ids=( "${all_ids[@]%/}" ) # remove the trailing "/" from each item
printf 'Found ID: %s\n' "${all_ids[@]}" >&2
n=0
ids=( "${all_ids[@]:0:8}" ) # pick out the first eight IDs
# Loop until the first ID in the ids array is empty
while [ -n "${ids[0]}" ] ; do
printf 'Processing ID: %s\n' "${ids[@]}" >&2
/usr/bin/time -f "$timefmt" \
fmriprep /input /output participant \
--fs-license-file /opt/freesurfer/license.txt \
--fs-no-reconall --use-aroma \
--ignore fieldmaps --n_cpus 12 --force-bbr \
--participant_label "${ids[@]}" \
-w /output
n=$(( n + 1 ))
ids=( "${all_ids[@]:n*8:8}" ) # pick out the next eight IDs
done