كيفية استخدام SSH لتشغيل برنامج نصي shell على جهاز بعيد؟




sysadmin remote-execution (7)

لا بد لي من تشغيل برنامج نصي شل (ويندوز / لينكس) على جهاز بعيد.

لدي SSH تكوين على كل من الجهاز A و B. النص البرمجي الخاص بي على الجهاز A الذي سيقوم بتشغيل بعض التعليمة البرمجية الخاصة بي على جهاز بعيد ، الجهاز B.

يمكن أن تكون أجهزة الكمبيوتر المحلية والبعيدة بنظام Windows أو Unix.

هل هناك طريقة لتشغيل ذلك باستخدام plink / ssh؟


أولاً ، قم بنسخ البرنامج النصي إلى Machine B باستخدام scp

[user @ machineA] $ scp / path / to / script user @ machineB: / home / user / path

ثم ، فقط قم بتشغيل البرنامج النصي

[user @ machineA] $ ssh user @ machineB "/ home / user / path / script"

سيعمل هذا إذا أعطيت إذنًا قابلاً للتنفيذ للبرنامج النصي.


أيضا ، لا تنسى الهروب من المتغيرات إذا كنت تريد التقاطها من مضيف الوجهة.

لقد أوقعني هذا في الماضي.

فمثلا:

[email protected]> ssh [email protected] "echo \$HOME"

يطبع / المنزل / user2

في حين

[email protected]> ssh [email protected] "echo $HOME"

يطبع / الوطن / المستخدم

مثال آخر:

[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"

يطبع "مرحبا" بشكل صحيح.


الجواب هنا ( https://.com/a/2732991/4752883 ) يعمل بشكل جيد إذا كنت تحاول تشغيل برنامج نصي على جهاز لينكس عن بعد باستخدام plink أو ssh . ستعمل إذا كان البرنامج النصي يحتوي على خطوط متعددة على linux .

** ومع ذلك ، إذا كنت تحاول تشغيل البرنامج النصي الدفعي الموجود على جهاز linux/windows محلي linux/windows البعيد هو Windows ، ويتكون من عدة أسطر باستخدام **

plink [email protected] -m local_script.bat

لن تعمل.

سيتم تنفيذ السطر الأول من النص البرمجي فقط. هذا هو على الأرجح الحد من plink .

الحل 1:

لتشغيل برنامج نصي دفعة متعددة (خاصة إذا كان بسيطًا نسبيًا ، يتكون من أسطر قليلة):

إذا كان البرنامج النصي الدفعي الأصلي كما يلي

cd C:\Users\ipython_user\Desktop 
python filename.py

يمكنك الجمع بين السطور معًا باستخدام الفاصل "&&" كما يلي في ملف local_script.bat : https://.com/a/8055390/4752883 :

cd C:\Users\ipython_user\Desktop && python filename.py

بعد هذا التغيير ، يمكنك بعد ذلك تشغيل النص البرمجي كما هو موضح هنا من قِبل @ JasonR.Coombs: https://.com/a/2732991/4752883 مع:

`plink [email protected] -m local_script.bat`

الحل 2:

إذا كان البرنامج النصي الدفعي معقدًا نسبيًا ، فقد يكون من الأفضل استخدام البرنامج النصي الدفعي الذي يقوم بتغليف أمر plink كما يلي كما هو موضح هنا من قبلMartin https://.com/a/32196999/4752883 :

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe


لقد بدأت استخدام Fabric for عمليات أكثر تعقيدًا. يتطلب النسيج بايثون واثنين من التبعيات الأخرى ، ولكن فقط على جهاز العميل. لا يحتاج الخادم إلا إلى خادم ssh. أجد هذه الأداة أقوى بكثير من نصوص القوالب التي تم تسليمها إلى SSH ، وهي تستحق عناء الإعداد (خاصة إذا كنت تستمتع بالبرمجة في Python). يساعد النسيج على تشغيل البرامج النصية على مضيفين متعددين (أو مضيفين لأدوار معينة) ، ويساعد على تسهيل عمليات idempotent (مثل إضافة سطر إلى نص التعليمة البرمجية ، ولكن ليس إذا كان موجودًا بالفعل) ، ويسمح ببناء منطق أكثر تعقيدًا (مثل Python اللغة يمكن أن توفر).


هذا امتداد لإجابة YarekT على الجمع بين الأوامر البينية المضمنة مع تمرير متغيرات ENV من الجهاز المحلي إلى المضيف البعيد حتى يمكنك إضفاء الطابع البرمجي على البرامج النصية الخاصة بك على الجانب البعيد:

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH

لقد وجدت هذا مفيدًا بشكل استثنائي من خلال الاحتفاظ بكل شيء في نص واحد بحيث يمكن قراءته وقراءته.

لماذا هذا يعمل. يدعم ssh بناء الجملة التالي:

ssh user @ host remote_command

في باش ، يمكننا تحديد متغيرات البيئة المراد تحديدها قبل تشغيل أمر في سطر واحد كما يلي:

ENV_VAR_1 = 'value1' ENV_VAR_2 = 'value2' bash -c 'echo $ ENV_VAR_1 $ ENV_VAR_2'

هذا يجعل من السهل تحديد المتغيرات قبل تشغيل الأمر. في هذه الحالة صدى هو أمرنا نحن قيد التشغيل. كل شيء قبل الصدى يعرف متغيرات البيئة.

لذا نجمع بين هاتين الميزتين وإجابة YarekT للحصول على:

ssh user @ host ARG1 = $ ARG1 ARG2 = $ ARG2 'bash -s' << 'ENDSSH' ...

في هذه الحالة ، يتم إعداد ARG1 و ARG2 إلى القيم المحلية. إرسال كل شيء بعد user @ host مثل remote_command. عندما يقوم الجهاز البعيد بتنفيذ الأمر ARG1 و ARG2 يتم تعيين القيم المحلية ، وذلك بفضل تقييم سطر الأوامر المحلي ، الذي يحدد متغيرات البيئة على الخادم البعيد ، ثم ينفذ الأمر bash -s باستخدام تلك المتغيرات. فويلا.


<hostA_shell_prompt>$ ssh [email protected] "ls -la"

سيطالبك ذلك بكلمة المرور ، ما لم تكن قد نسخت المفتاح العمومي لمضيف hostA إلى ملف authorized_keys في دليل المستخدم الخاص بـ .ssh. سيسمح ذلك بالتوثيق بدون كلمة مرور (إذا تم قبوله كطريقة مصادقة على تهيئة خادم ssh)







remote-execution