Как передать пустую строку с двойными кавычками в bash script?

Я пытаюсь написать script, который примет в качестве дополнительных аргументов в командной строке пустую строку с двойными кавычками. Я хочу, чтобы script передал эти аргументы вместе с двойной кавычкой пустой строки, если это предусмотрено, но вместо этого интерпретатор команд интерпретирует такой аргумент как пустую строку и удаляет кавычки. Есть какой-либо способ сделать это?

В качестве простого примера я хотел бы иметь в файле script.sh:

#!/bin/bash
/home/myapp $1 $2

Если я запустил приглашение:

$ ./script.sh arg1 ""

script просто выполняет "/home/myapp arg1", но пропускает/игнорирует второй аргумент (""). Я хочу сохранить эту пустую строку и вместо этого выполнить: /home/myapp arg1 ""

Ответ 1

Вы можете определить, сколько позиционных параметров было передано вашему script на на проверку параметра $#. Например, если это 2 или больше, то вы знаете, что что-то было передано для $2, даже если $2 пуст (кавычки удалены вызовом оболочки). Следующее реализует эту логику и передает "" вызываемой программе (в данном случае echo), если параметр был принят, но пустой:

#!/bin/bash

if [ $# -ge 2 ]; then
    if [ "$2" ]; then
        arg2="$2"
    else
        arg2='""'
    fi
    echo "$1 $arg2"
elif [ $# == 1 ]; then
    echo "$1"
fi

Вывод:

$ ./args.sh a
a
$ ./args.sh a ""
a ""
$ ./args.sh a 1
a 1
$ 

Ответ 2

Вы правильно передаете пустой аргумент строки в script.

Это script, который испортил его:

#!/bin/bash
/home/myapp $1 $2

script не защищает расширение $1 и $2 от разбиения слов. Это означает, что если $1 и $2 содержат несколько слов, они превращаются в отдельные аргументы, и если любой из них расширяется до нуля, они просто исчезают.

Это должно быть:

#!/bin/bash
/home/myapp "$1" "$2"

В общем, вы можете сделать свой script передать все свои аргументы вызываемой программе, например:

/home/myapp "[email protected]"

Кавычки - это просто синтаксис оболочки; они не являются частью самих данных аргументов. Когда вы вводите program "" в оболочку, на уровне операционной системы программа получает пустую строку языка C: указатель на нулевой байт. Нет кавычек.

Вы можете передать аргумент "" (двухсимвольная строка из двух двойных кавычек), но это не пустой аргумент. Способ сделать это, например, '""': обернуть его в одинарные кавычки.

Единственная причина делать такие вещи - это когда вы манипулируете синтаксисом оболочки на метауровне: передавая фрагменты исходного кода оболочки script, такие как цитируемые токены, пустые или другие. Оболочка имеет команду под названием eval, которая берет исходный код в качестве аргумента (или нескольких аргументов) и оценивает его.

empty_shell_string_syntax='""'    # this variable holds the characters ""

eval empty_var=$empty_shell_string_syntax   # empty_var gets set to empty string

до вызова eval, командная строка может быть расширена. Это расширение удаляет синтаксис $empty_shell_string_sytnax и заменяет его содержимым, символы "". Итак, eval получает строку empty_var="". Он оценивает это, и поэтому empty_var устанавливается в пустую строку, как указывает синтаксис.

Ответ 3

В дополнение к Полезное объяснение Kaz:
Если вы пройдете "[email protected]" через, пустые аргументы будут пройдены, тоже:

#!/bin/bash

/home/myapp "[email protected]"

Прохождение через "[email protected]" сохраняет исходные аргументы точно так же, как переданные в четные аргументы, переданные как пустые строки (переданные как, например, '' или "" или "$someVar"), где переменная someVar не задана или содержит пустая строка).


Если может быть более 2 аргументов:

#!/bin/bash

# Copy the (up to) first 2 arguments - whether they're empty strings or not -
# to a separate array.
firstTwo=("${@:1:2}") 
shift; shift  # Remove the first 2 arguments from the arguments array.

# Invoke the app with the (up to) first 2 arguments stored in the new array.
/home/myapp "${firstTwo[@]}"

# Process the remaining arguments, if any.
for a; do
  echo "remaining: [$a]"
done

Ответ 4

Вы избежите его, используя обратную косую черту

$ ./script.sh arg1 \"\"

Может быть проверен, например. on echo:

$ echo \"\"
""

Ответ 5

Удалите их с помощью обратных косых черт или поместите их в одинарные кавычки.

Ответ 6

Вы также можете помещать их в одну цитату, чтобы иметь свои литеральные значения, например.:

  ]$ echo '""'
  ""

Например, в script:

   ]# cat a.bash
     #!/bin/bash        
     echo a$1b

  ]$ ./a.sh '""'
  a""b

  ]$ ./a.sh ""
  ab

Ответ 7

Попробуйте следующее:

cmd=yourcomand;
n=0; for a in "[email protected]"; do n=$((n +1)); cmd="$cmd \${$n+\"\$$n\"}"; done
eval $cmd