LINUX.ORG.RU
ФорумAdmin

Передать параметр bash в ssh

 ,


0

1

Добрый день, я новичек в линукс, потихоньку осваиваюсь. У меня вопрос господа. Есть локальный и удаленный серверы. Задача стоит удалить файл с удалённого сервера, при этом скрипт должен запускаться на локальном.

вот примерно сам скрипт, нужно обязательно передавать с параметром $1

#!/bin/bash
echo $1
logfile="/var/log/delete_file.log"
if [ -n "$1" ];then
`/usr/bin/find /var/lib/blablalba/* -type f -a  -name "$1" -exec rm -rf {} \; >> /dev/null 2>&1`
	if [ $? -eq 0 ] ;then
        sleep 1
        echo "DELETED ! ALL OK!." >> $logfile
        exit 0
	else
echo "`date +"%d.%m.%Y_%H:%M:%S"`  file ----> "$1" <---- NO DELETED ! Check script!" >> $logfile
        fi		
else
echo "`date +"%d.%m.%Y_%H:%M:%S"`  Parametr ----> "$1" <---- NOT FOUND ! Check script!" >> $logfile
		exit 1
fi

Что я делал :

/usr/bin/ssh remote_server@remote_ip 'bash -s' < "/var/lib/test_script/delete_file.sh --file.txt"

Ну и с ковычками туда-сюда манипуляции делал. Всегда выводит ошибку No such file or directory

upd

На удалённом сервере кусочек этого скрипта, отвечающий за поиск и удаление файла (по имени) без проблем находит этот файл:

/usr/bin/find /usr/bin/find /var/lib/blablalba/* -type f -name "file.txt"

связка по ключам ssh настроена. Права все выданы [вроде все].



Последнее исправление: Sv00p (всего исправлений: 1)

> /usr/bin/ssh remote_server@remote_ip 'bash -s' < "/var/lib/test_script/delete_file.sh --file.txt"

Объясни, как по-твоему должна работать эта команда? Какие программы где и как запускаются, что передаётся по сети?

В частности, что значит символ «<» у неё в середине и к кому он применяется.

И ещё, к проблеме это не относится, но не надо писать скрипты на баше. Скрипты пишут на posix-шелле (/bin/sh).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 5)
Ответ на: комментарий от firkax

Любопытно, почему на баше скрипты писать не надо? В современных системах всё равно /bin/sh - это симлинк к башу, а о совместимости между разными дистрибутивами приходится только мечтать

GLaDOS
()
Ответ на: комментарий от GLaDOS

В современных системах всё равно /bin/sh - это симлинк к башу

Враньё явное и второе враньё подразумеваемое тут же. Во-первых,

$ ls -al /bin/sh
lrwxrwxrwx 1 root root 4 дек 10  2020 /bin/sh -> dash
$ ls -al /bin/sh                     
-r-xr-xr-x  1 root  wheel  145712 Jul 21  2020 /bin/sh

на нормальных современных системах так.

Во-вторых, баш, будучи запущен с именем sh, включает posix-режим, так что /bin/bash и /bin/sh даже с симлинком на баш - это разные вещи.

а о совместимости между разными дистрибутивами приходится только мечтать

Вот чтобы о совместимости не мечтать, а иметь, и надо пользоваться стандартным шеллом /bin/sh.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Ничего не знаю. На шляпе вот так :) ls -la /bin/sh lrwxrwxrwx. 1 root root 4 окт 14 20:34 /bin/sh -> bash

Вот чтобы о совместимости не мечтать, а иметь, и надо пользоваться стандартным шеллом /bin/sh.

Да тут даже не в шелле, и не в позиксе дело. Никто же не запускает чистые вычисления на голом шелле, так или иначе скрипт будет дёргать прикладные утилиты, тот же curl, например. И о какой совместимости можно говорить, когда курл есть не во всех дистрибутивах. Я даже не говорю о разных флагах версиях прикладных утилит.

Если нужно чтобы везде работало - пишут на питоне, либо на ансибле.

GLaDOS
()
Ответ на: комментарий от GLaDOS

И о какой совместимости можно говорить, когда курл есть не во всех дистрибутивах. Я даже не говорю о разных флагах версиях прикладных утилит.

Я не знаю чего все так любят curl, когда есть более удобный и более распространённый wget. Но это мало чего меняет, наверно. Да, некоторые утилиты где-то есть, где-то нет. А вот /bin/sh есть везде, и хотя бы с ним путаницу добавлять не надо.

пишут на питоне, либо на ансибле

Круто, чтобы избежать проблем с отсутствующей скачивалкой, тянем отсутствующий интерпретатор.

Отмечу, что автору скачивать ничего не надо, ему надо найти и удалить файл, это будет работать везде. А вот даже шебанг /bin/bash уже может всё сломать если баша нет.

firkax ★★★★★
()
Ответ на: комментарий от GLaDOS

То есть на основной вопрос, про символ ″<″ вы решили не отвечать?

при этом скрипт должен запускаться на локальном.

И при этом вы пытаетесь выполнить скрипт на удалённом компьютере, на локальном у вас скрипт не запускается, а только хранится в файле.

Вобще странно, вы не хотите posix-sh, хотите bash, но при этом find у вас posix (так как во FreeBSD и GNU find c 2004 года) вместо ″exec rm″ принято писать ″delete″.

mky ★★★★★
()

Что я делал : /usr/bin/ssh remote_server@remote_ip ‘bash -s’ < «/var/lib/test_script/delete_file.sh –file.txt»

а почему --file.txt? зачем -- перед именем файла?

Да и беда еще в find. $? не будет 0, если нет прав на просмотр всего в /var/lib/blablalba/*

lnx
()

Параметр — только передачей полной команды с параметрами в ssh, как в примере firkax.

Если сможешь переписать скрипт (чтобы он тебе всю систему не удалил), то можно скармливать ему вместо аргумента переменную, а её в свою очередь передавать по ssh с помощью директивы SetEnv (или SendEnv, если переменная уже назначена на локальной машине). Для упрощения процесса можно прописать эти директивы в ssh_config(5) пользователя.

Только в скрипте обязательно нужны проверки на валидность пути и наличия файла, иначе неверно назначенная или пустая переменная удалят тебе то, что удалять не нужно, вплоть до системных файлов.

mord0d ★★★★★
()
Ответ на: комментарий от lnx

скрипт сотрёт файл с именем --debug

Нет. bash напишет про ″invalid option″.

А попробуй ″--″

Именно так и работает:

ssh remote_user@remote_ip -- "bash -s --" < /var/lib/test_script/delete_file.sh file.txt
И двойная чёрточка хорошо визуально отделяет аргументы команды ssh от удалённо выполняемой команды.

mky ★★★★★
()

Задачка, видимо, учебная? Очень своеобразная постановка и ограничения.

Вообще, запускать find, чтобы он ходил-бродил - кажется избыточно и даже опасно. Да ещё и с rm -rf {}. Почему бы не указывать чёткий путь до объекта? Или даже по маске, если надо.

Ну и всё куда проще: при скриптовании строчки с ssh, переменная раскроется ДО подключения (если от этого специально не защититься), так что в минимальном варианте, всё будет выглядеть так:

$ ./test-remote-delete.sh /tmp/testfile_[1,5]
removed ‘/tmp/testfile_1’
removed ‘/tmp/testfile_5’
$ ./test-remote-delete.sh /tmp/testfile*
removed ‘/tmp/testfile_qwe’

Сам упрощённый скрипт:

#!/bin/bash

OBJECT=$1

ssh USER@SERVER rm -fv $OBJECT

Примитив? Но все выдвинутые условия выполнены жи :)

А проталкивать через SSH на удалённый сервер кирзовым сапогом могострочную портянку со множеством спецсимволов - так это заведомо тухлое мероприятие, с непонятными мотивами.

NDfan
()
Ответ на: комментарий от mky

То есть на основной вопрос, про символ ″<″ вы решили не отвечать?

По-моему, этот ‘<’ подаёт файл на stdin у ssh локально. Что при этом делает ssh мне непонятно, но можно предположить, что он передаёт этот контент на удалённый сервер, на stdin запущенной программе. Но это неточно.

Shushundr ★★★★
()
Ответ на: комментарий от firkax

Нагуглил на скорую ногу на стаке https://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-a-local-shell-script-on-a-remote-machine

ssh root@MachineB 'bash -s' < local_script.sh

You shouldn't have to copy the script to the remote server to run it.

и решил так попробовать.Символ стрелки типа передаёт локальный скрипт с параметрами в оболочку ‘bash -s’ удалённого хоста. Наверно всё не так. Но вот такие попытки были. попробую другие варианты. если не получится как предлагают - закину скрипт на удалённый хост и туда без проблем передам и скрипт и параметр по ссх. Пока пытаюсь задачу решить, если скрипт на локальном хосте лежит, а его содержимое для удалённого хоста предназначено

Sv00p
() автор топика
Ответ на: комментарий от mky

Ты прав, спасибо, у меня именно так и срабатывает. Вот то что мне нужно!!

итоговая команда такова (у меня)

/usr/bin/ssh remote_server@remote_ip --"bash -s --" < /var/lib/test_script/delete_file.sh file.txt

Sv00p
() автор топика
Ответ на: комментарий от lnx

И так тоже срабатывает, спасибо!!!

Теперь две команды действующие

/usr/bin/ssh remote_server@remote_ip --"bash -s --" < /var/lib/test_script/delete_file.sh file.txt

  и

/usr/bin/ssh remote_server@remote_ip "bash -s" -- < /var/lib/test_script/delete_file.sh file.txt

Ура. Спасибо всем за хелп!

Sv00p
() автор топика
Ответ на: комментарий от NDfan

А проталкивать через SSH на удалённый сервер кирзовым сапогом могострочную портянку

Эм. Это точно не очень правильно? Файлы же передают вроде по ssh, чем строки с буквами и символами хуже? Как-никак tcp сессия же.

Sv00p
() автор топика
Ответ на: комментарий от lnx

Интерестно, всегда считал, что первый ″--″ воспринимается как аргумент и не передаётся дальше. Но получается, что ″-- bash -s ...″ запустит ″bash -s ...″. А ″bash -s -- ...″ запустит ″bash -s --...″, то есть ″--″ будет проанализирован, но передан дальше. Запомню.

mky ★★★★★
()
Ответ на: комментарий от Sv00p

Эм. Это точно не очень правильно? Файлы же передают вроде по ssh, чем строки с буквами и символами хуже? Как-никак tcp сессия же.

В плане передачи, конечно, проблем нет. Тут скорее сама необходимость таких кульбитов, особенно для прод-решений, сильно для меня сомнительна )

Но тема получилась прикольная и познавательная, в любом случае.

NDfan
()
17 февраля 2024 г.