Использование подоболочки для передачи параметров с пробелами

Я не знаком с opkg, чтобы знать, предоставляет ли он собственный индикатор выполнения; ближе всего я вижу уровень детализации -V . Если лучшего решения нет, то вы можете сохранить приведенный ниже сценарий (скажем, в файл с именем jspb ), сделать его исполняемым ( chmod u + x jspb ), а затем вызвать jspb opkg upgrade packagename , чтобы получить индикатор выполнения .

Есть лучшие способы создания индикаторов выполнения, но я хотел написать что-то, что имитировало бы индикатор выполнения. У него одно главное требование: наличие псевдофайловой системы / proc, чтобы она могла отслеживать ход выполнения задания, которое вы ей даете. В остальном это довольно упрощенно и поэтому должно работать в большинстве оболочек (проверено в bash, ksh, dash и Bourne sh). Поскольку он настолько портативен, shellcheck справедливо жалуется на «устаревшие» и «устаревшие» конструкции, которые использует скрипт. Ему действительно удается грамотно заполнить столбцы вашего экрана - попробуйте изменить размер окна в середине обновления!

#!/bin/sh

# Jeff's progress bar
# *simulates* a progress bar

# better options:
# https://github.com/Xfennec/progress
# http://www.theiling.de/projects/bar.html

if [ ! -n "$*" ]
then
  echo Nothing to do, exiting!
  exit 0
fi

if [ ! -d /proc/$$ ]
then
  echo Missing /proc, sorry
  exit 1
fi

sh -c "$*" &
PID=$!
# give the command a chance to fail immediately, if it will
sleep 1

# dash, Bourne sh do not have $RANDOM
HAVERANDOM=0
if [ -n "$RANDOM" ]
then
  HAVERANDOM=1
fi

i=1
while [ -d /proc/$PID ]
do
  # simulate progress
  if [ $HAVERANDOM ]
  then
    sleep `expr $RANDOM % 4`
  else
    sleep `expr $i % 4`
  fi

  # see if our window got resized
  cols=`tput cols`
  if [ $i -ge $cols ]
  then
    printf "\r"
    # clear out the old progress bar and start over!
    while [ $i -gt 1 ]
    do
      printf " "
      i=`expr $i - 1`
    done
    printf "\r"
  fi
  # making progress!
  printf "#"
  i=`expr $i + 1`
done

# only clear the progress bar it if we wrote something
if [ $i -gt 1 ]
then
  pacman=1
  printf "\r"
  while [ $pacman -lt $i ]
  do
    printf " "
    pacman=`expr $pacman + 1`
  done
  printf "\r"
fi

Главная копия находится на Github

1
02.07.2017, 20:55
2 ответа

Да. Установите переменную IFS(, которая обычно содержит пробел, табуляцию, новую строку ), чтобы она была просто новой строкой. Таким образом, пробелы и табуляции не будут использоваться для разделения слов. Это даст вам желаемый результат.

IFS=$'\n'
set -o noglob # disable the second effect of leaving that
              # $(...) unquoted.
./name_value.sh $(echo "no_spaces"; echo "with spaces")

Однако я бы сделал так, чтобы сценарий считывался со стандартного ввода.

# name_value.sh
IFS= read -r name
IFS= read -r value
echo "Name=$name"
echo "Value=$value"

, затем

( echo no_spaces; echo with spaces ) |./name_value.sh

Я думаю, что этот подход более надежен.

4
28.04.2021, 23:59

При использовании этой команды

./name_value.sh $(echo "no_spaces"; echo "with spaces")

bash выполняет команды «вложенных оболочек» в «$()» и возвращает выходную строку

Пример

Ввод command:./name_value.sh $(echo "без_пробелов"; echo "с пробелами")

Обработанная команда: ./name_value.sh без_пробелов с пробелами

Следующим шагом будет выполнение bash скрипт с тремя аргументами

Первый аргумент: no_space

Второй аргумент: с

Третий аргумент: пробелы


Это то же самое, что и вызов скрипта вручную командой

./name_value.sh no_spaces with spaces

Чтобы решить вашу проблему, вам нужно вставить кавычки вокруг вызова под-оболочки "$()"

Вам нужно это

./name_value.sh $(echo "no_spaces") "$(echo "with spaces")"

И обработанная вами команда

./name_value.sh no_spaces "with spaces"

И, наконец, вы выведете ее

Name=no_spaces
Value=with spaces
1
28.04.2021, 23:59

Теги

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