Выполнять скрипт Bash удаленно через cURL

У меня есть простой сценарий Bash, который принимает входные данные и печатает несколько строк с этими входами

fortinetTest.sh

read -p "Enter SSC IP: $ip " ip && ip=${ip:-1.1.1.1}
printf "\n"

#check IP validation
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "SSC IP: $ip"
  printf "\n"
else
  echo "Enter a valid SSC IP address. Ex. 1.1.1.1"
  exit
fi

enter image description here

Я попытался загрузить их на свой сервер, а затем попытаться запустить его через curl

enter image description here

Я не уверен, почему приглашение ввода никогда не срабатывает, когда я использую cURL/wget.

Я что-то пропустил?

Ответ 1

С curl... | bash curl... | bash, bash stdin читает скрипт, поэтому stdin недоступен для команды read.

Попробуйте использовать подстановку процессов, чтобы вызвать удаленный скрипт как локальный файл:

bash <( curl -s ... )

Ответ 2

Ваша проблема может быть просто воспроизведена, запустив скрипт, как показано ниже.

$ cat test.sh | bash
Enter a valid SSC IP address. Ex. 1.1.1.1

Это потому, что bash, который вы запускаете с помощью pipe, не получает TTY, когда вы read -p он считывается из stdin который является содержимым test.sh в этом случае. Так что проблема не в завитке. Вопрос не читается с tty

Таким образом, исправление заключается в том, чтобы убедиться, что вы готовы от tty

read < /dev/tty -p "Enter SSC IP: $ip " ip && ip=${ip:-1.1.1.1}
printf "\n"

#check IP validation
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "SSC IP: $ip"
  printf "\n"
else
  echo "Enter a valid SSC IP address. Ex. 1.1.1.1"
  exit
fi

Как только вы это сделаете, даже curl начнет работать

[email protected]:/var/www/html$ curl -s localhost/test.sh | bash
Enter SSC IP:  2.2.2.2

SSC IP: 2.2.2.2

Ответ 3

Я лично предпочитаю source <(curl -s localhost/test.sh). Хотя это похоже на bash..., одна существенная разница заключается в том, как обрабатываются процессы.

bash приведет к созданию нового процесса, и этот процесс вызовет команды из сценария.
source с другой стороны, будет использовать текущий процесс для вызова команд из сценария.

В некоторых случаях это может сыграть ключевую роль. Я признаю, что это не очень часто.

Чтобы продемонстрировать, выполните следующие действия:

### Open Two Terminals
# In the first terminal run:
echo "sleep 5" > ./myTest.sh
bash ./myTest.sh

# Switch to the second terminal and run:
ps -efjh

## Repeat the same with _source_ command
# In the first terminal run:
source ./myTest.sh

# Switch to the second terminal and run:
ps -efjh

Результаты должны выглядеть примерно так:

Перед выполнением:

before

Запуск bash (основной + два подпроцесса):

bash

source (основной + один подпроцесс):

source

ОБНОВЛЕНИЕ: Разница в использовании использования переменных bash и source:

source команда будет использовать вашу текущую среду. Это означает, что после выполнения все изменения и объявления переменных, созданные скриптом, будут доступны в вашем приглашении.

bash с другой стороны, будет работать как другой процесс; поэтому все переменные будут отброшены, когда процесс завершится.

Я думаю, что все согласятся, что для каждого метода есть преимущества и недостатки. Вам просто нужно решить, какой из них лучше для вашего случая использования.

## Test for variables declared by the script:
echo "test_var3='Some Other Value'" > ./myTest3.sh
bash ./myTest3.sh
echo $test_var3
source ./myTest3.sh
echo $test_var3

Testing setting environment variables by the script

## Test for usability of current environment variables:
test_var="Some Value" # Setting a variable
echo "echo $test_var" > myTest2.sh # Creating a test script
chmod +x ./myTest2.sh # Adding execute permission
## Executing:
. myTest2.sh
bash ./myTest2.sh
source ./myTest2.sh
./myTest2.sh
## All of the above results should print the variable.

Testing access to environment variables with different execution methods.

Надеюсь, это поможет.