ssh และ shell ผ่าน ssh: จะออกอย่างไร


22

ฉันเปิดตัวสคริปต์ที่ห่างไกลผ่าน SSH เช่นนี้:

ssh user@ipaddress '~/my_script.sh'

ทุกอย่างกำลังดี แต่เมื่อสคริปต์เสร็จสิ้นการเชื่อมต่อจะไม่ปิด ฉันต้องกด CTRL-C เพื่อหยุดการเชื่อมต่อปัจจุบัน

ฉันได้ลองใช้คำสั่ง "exit" ใน '~ / my_script.sh' และมันไร้ประโยชน์ ฉันได้ลองใช้คำสั่ง "ออกจากระบบ" ใน '~ / my_script.sh' และได้รับข้อความ:

logout: not login shell: use exit

...

มีความคิดใดที่ฉันจะปิดโดยอัตโนมัติและ SSH อย่างถูกต้องเมื่อสคริปต์เสร็จสิ้น?

(การแก้ไขเพื่อความกระจ่าง :) นี่คือสิ่งที่อยู่ในสคริปต์ของฉัน:

#!/bin/sh
path_sources_qas=/sources/QuickAddress/
path_qas_bin=/usr/bin/qas

umount_disque_qas()
{
  # Umount du disque 'qas' s'il n'avait pas été 'umount' :
  nom_disque_monte=`cat /etc/mtab | grep qas | awk '{ print $2}'`
  if [ "$nom_disque_monte" != "" ]
  then
    echo "For safety, umount : $nom_disque_monte"
    umount $nom_disque_monte
  fi

}

# Umount twice (we never know if a st***d guy mounted it twice) :
umount_disque_qas
umount_disque_qas

echo "--------------------------------"
echo "Install ISO quick address..."
nom_fichier_iso=`ls -t $path_sources_qas | awk '{if (NR==1) {print $1}}'`
echo "Mount disk $nom_fichier_iso..."
mount -o loop -t iso9660 $path_sources_qas/$nom_fichier_iso /mnt/qas
echo "Done."

# All the folders are like this :
# /usr/bin/qas/Data.old.10
# /usr/bin/qas/Data.old.11
# /usr/bin/qas/Data.old.12
# ...

echo "--------------------------------"
echo "Stopping QuickAdress server..."
cd $path_qas_bin/apps/
./wvmgmtd shutdown qaserver:2021
sleep 3
echo "Done."

# Get last number of the folder:
num_dernier_dossier_backup=`ls -Atd $path_qas_bin/Data.old* | awk '{if (NR==1) {print $1}}' | awk -F . '{print $NF}'`
# Add 1 :
let "num_dernier_dossier_backup += 1"
# Full name :
nom_dossier_backup=Data.old.$num_dernier_dossier_backup
echo "--------------------------------"
echo "Saving Data to $nom_dossier_backup..."
cd $path_qas_bin
mv Data $nom_dossier_backup
echo "Done."


echo "--------------------------------"
echo "Copying new folder Data..."
cd $path_qas_bin
cp -r /mnt/qas/Data .
echo "Done."

echo "--------------------------------"
echo "Deleting unused datas..."
cd $path_qas_bin/apps/
rm -f $path_qas_bin/Data/frxmos.dap
echo "Done."

echo "--------------------------------"
echo "Restart server..."
cd $path_qas_bin/apps/
./qaswvd &
sleep 3
echo "Done."
sleep 3

echo "--------------------------------"
echo "Check: server state: you should read 'OK':"
./wvmgmtd srvlist
echo "Done."

echo "--------------------------------"
echo "Check: active licences (only one here):"
./wvmgmtd licencelistread qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: counters: number of addresses left:"
./wvmgmtd counterinforead qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: Datasets avalaibles:"
./wvmgmtd datalistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: "meters" for "licence by click":"
./wvmgmtd meterslistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Removing virtual disk..."
umount_disque_qas
echo "Done."

echo "All done"
echo "Click 'Ctrl-C' to quit."

exit

เมื่อฉันเปิดใช้งานผ่าน SSH มันจะทำงานและในตอนท้ายฉันอ่าน"เสร็จแล้ว" ดังนั้นวิธีการนี้จะถึงช่วง 2 เส้น

ความคิดใด ๆ ที่ฉันสามารถทำได้เพื่อปิดโดยอัตโนมัติและราคา


1
ในสคริปต์คืออะไร
Ignacio Vazquez-Abrams

@Olivier: คุณส่งต่อพอร์ตใด ๆ (รวมถึงตัวแทนและ X) หรือไม่ การเชื่อมต่อ ssh ถูกปิดเมื่อคำสั่งสิ้นสุดและการเชื่อมต่อ TCP ทั้งหมดถูกปิด
Gilles 'หยุดความชั่วร้าย'

@Gilles: ไม่ฉันเพิ่งสร้างเชลล์เชื่อมต่อเพื่อเรียกใช้สคริปต์ไม่มีอะไรถูกส่งต่อ
Olivier Pons

1
@ Olivier: หากคุณมี~/.ssh/configลองโดยไม่ผ่านมันและผ่านตัวเลือก-a -x(และไม่-o) sshเพื่อให้แน่ใจว่าไม่มีการส่งต่อเกิดขึ้น หากยังใช้งานไม่ได้ให้แสดงเนื้อหาของสคริปต์
Gilles 'หยุดความชั่วร้าย'

@Olivier: สคริปต์เริ่มทำงานเบื้องหลังใด ๆ ที่อาจรออยู่หรือไม่ น่าเสียดายที่งานดูเหมือนจะไม่ส่งคืนสิ่งใดเมื่ออยู่ในสคริปต์ ssh ตัวอย่าง: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'จะแสดงรายการไฟล์แสดงเสร็จแล้วรอ 10 วินาทีก่อนกลับมา
asoundmove

คำตอบ:


19

การออกในเชลล์สคริปต์ไม่ทำงานเนื่องจากออกจากสคริปต์ไม่ใช่เชลล์ หากต้องการออกจากเชลล์หลังจากสคริปต์เสร็จสิ้นให้ทำ

ssh user@ipaddress '~/my_script.sh && exit'

สิ่งนี้จะรันสคริปต์จากนั้นออกจากเชลล์


3
มันควรจะออก สคริปต์คือเชลล์
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

@Dennis: มันไม่ได้ผลสำหรับเขาดังนั้นมันจึงใช้งานได้
Wuffers

2
@นาย. ชาย: คำสั่งของคุณคือเทียบเท่ากับต้นฉบับยกเว้นว่ามันบังคับให้เปลือกจะมีชีวิตอยู่ระหว่างเปลือกหอยและการทำงานsshd คุณเขียนจะทำหน้าที่เมื่อออกจากสคริปต์ซึ่งไม่ได้ช่วย วิธีเดียวที่โซลูชันของคุณสามารถทำงานได้คือถ้าสคริปต์ทำบางสิ่งที่แปลกประหลาดเมื่อแม่ของมันเป็นและไม่ได้ทำสิ่งที่แปลกประหลาดเมื่อแม่ของมันเป็นเปลือก myscript.shexitsshd
Gilles 'หยุดความชั่วร้าย'

มันช่วยไม่ได้อย่างไร ออกจะปิดเปลือกและยุติการเชื่อมต่อถูกต้องหรือไม่ และนี่ไม่ใช่สิ่งที่ผู้ลงประกาศต้องการจะทำ?
Wuffers

3
@MrMan: ~/my_script.sh && exitออกทันทีที่~/my_script.shออก หากเชลล์สคริปต์ไม่ออกจากการทำงานคำสั่งของคุณจะไม่ไปถึงจุดexitนั้น ดังนั้นมันจึงไร้ประโยชน์
Gilles 'หยุดความชั่วร้าย'

12

การเชื่อมต่อ ssh ยังคงเปิดอยู่เมื่อกระบวนการเริ่มต้นโดย ssh (ที่นี่เชลล์) ออกหากมีกระบวนการอื่นที่ยังคงใช้อยู่ ฉันไม่ทราบกฎที่แน่นอนที่ ssh daemon ติดตาม แต่มีการใช้งานการเชื่อมต่ออย่างน้อยหากเอาต์พุตมาตรฐานของกระบวนการลูกใด ๆ ยังคงเชื่อมต่อกับไพพ์ดั้งเดิมที่จัดเตรียมโดย ssh เปรียบเทียบ:

ssh somehost 'sleep 5 &'  # exits after 5 seconds
ssh somehost 'sleep 5 >/dev/null &'  # exits immediately seconds

เมื่อคุณเริ่มต้นภูตคุณควรพื้นหลังและปิดตัวอธิบายไฟล์ อย่างน้อยใช้สิ่งนี้:

./qaswvd </dev/null >/dev/null 2>/dev/null &

คุณอาจต้องการเพิ่มnohupข้างหน้า; มันจะไม่สร้างความแตกต่างที่นี่ แต่จะมีประโยชน์หากสคริปต์ถูกเรียกใช้จากเทอร์มินัล โปรแกรมจำนวนมากที่ออกแบบมาเพื่อทำหน้าที่เป็น daemon มีตัวเลือกบรรทัดคำสั่งเพื่อให้พวกมันแยกปิดตัวอธิบายไฟล์ละเว้นสัญญาณและสิ่งอื่น ๆ ตรวจสอบในqaswvdเอกสารว่ามีหรือไม่ คุณสามารถตรวจสอบโปรแกรมอรรถประโยชน์“ daemonizer”


มีปัญหาเดียวกันและใช้งานได้ คำตอบที่ยอมรับไม่ทำงาน
Andy

5

ฉันเห็นโพสต์นี้เมื่อฉัน googled สำหรับการแก้ปัญหาในสถานการณ์เดียวกัน แม้ว่าจะสายเกินไปที่จะแก้ปัญหาของ @ Oliver เนื่องจากคำตอบที่ได้รับการยอมรับนั้นชัดเจนว่าไม่ได้ทำงานกับ OP หรือฉัน (ไม่รู้ว่าทำไมมันถึงได้รับการยอมรับ) ฉันยังต้องการโพสต์คำตอบของตัวเองสำหรับ googler ในอนาคต ง่ายมาก: เพิ่ม-fตัวเลือกในsshคำสั่ง:

ssh -f user@ipaddress '~/my_script.sh'

แก้ไข

เอฟเฟกต์ของ-fตัวเลือกคือการใส่sshพื้นหลังดังนั้นโดยไม่เพิ่มตัวเลือกใด ๆ เพิ่มเติมเป็นไปได้ว่าการเชื่อมต่อยังมีชีวิตอยู่แม้จะดูเหมือนว่ามันจะเสีย หนึ่งอาจหมายถึงคำตอบที่ได้รับในโพสต์อื่นในเว็บไซต์นี้หากสนใจ


ข้อควรระวัง: นี่ (-f) จะไม่ทำงานหากสคริปต์ต้นฉบับมีพร้อมท์สำหรับการป้อนข้อมูลของผู้ใช้
madD7

3

เช่นเดียวกับอิกนาชิโอฉันอยากรู้ว่ามีอะไรในสคริปต์ของคุณ

บางทีคุณอาจลองและลดสคริปต์ของคุณเป็นตัวอย่างที่เล็กที่สุดที่เป็นไปได้ที่ทำให้เกิดข้อผิดพลาด

หรือเริ่มจากสคริปต์ที่ว่างเปล่าและเพิ่มคำสั่งในแต่ละครั้งจนกว่าคุณจะเห็นปัญหาจากนั้นคุณจะรู้ว่าคำสั่งใดที่ทำให้สคริปต์ของคุณล็อค

หากสคริปต์เปล่าทำให้คุณเกิดปัญหาคุณอาจต้องการตรวจสอบการกำหนดค่า ssh ของคุณตัวอย่างเช่น. bash_logout หรือบางอย่างที่เรียกว่าเมื่อออกที่อาจทำให้เกิดปัญหาหรือไม่


ขอบคุณสำหรับคำแนะนำตอนนี้ฉันได้เพิ่มตัวอย่างสคริปต์ของฉันในคำถามของฉัน
Olivier Pons

@Olivier: คุณได้เพิ่มเฉพาะส่วนที่ไม่เกี่ยวข้องในสคริปต์ของคุณ โพสต์สคริปต์ (และคำแนะนำการใช้งานหากจำเป็น) ที่จะช่วยให้ผู้อ่านสร้างปัญหาของคุณได้ ลดความซับซ้อนของสคริปต์ให้มากที่สุดเท่าที่เป็นไปได้ แต่ไม่ต้องเพิ่มเติม
Gilles 'หยุดความชั่วร้าย'

@Gilles ขอบคุณ ฉันได้แก้ไขคำถามของฉันและเพิ่มทั้งสคริปต์ หวังว่านี่จะช่วยได้ ดูเหมือนว่าปัญหาอาจเป็นข้อเท็จจริงที่ว่าฉันกำลังเปิดตัวกระบวนการพื้นหลัง ( บรรทัด "./qaswvd &" ) นี่อาจเป็นสาเหตุของปัญหาหรือไม่
Olivier Pons

1
@Olivier: ใช่กระบวนการหลักของคุณจะรอให้กระบวนการส่วนหลังหยุดก่อนที่จะออก หากคุณต้องการให้บางสิ่งบางอย่างยังคงทำงานหลังจากที่คุณออกจากคุณอาจต้องการลอง nohup ไม่แน่ใจว่ามันใช้งานได้กับ ssh แต่ให้ลองมันจะไม่เจ็บ
asoundmove

2

คุณอาจใช้งานในสคริปต์ของคุณ ถ้านั่นคือเชลล์เคสรอให้งานของคุณเสร็จและไม่ต้องการแยกตัว

ฉันจะไม่โพสต์ใหม่จะส่งต่อให้คุณhttp://en.wikipedia.org/wiki/Nohup#Existing_jobs


ฉันได้แก้ไขคำถามของฉันและเพิ่มทั้งสคริปต์ หวังว่านี่จะช่วยได้ ดูเหมือนว่าปัญหาอาจเป็นข้อเท็จจริงที่ว่าฉันกำลังเปิดตัวกระบวนการพื้นหลัง (บรรทัด "./qaswvd &") หากคุณพูดถูกสิ่งนี้อาจเป็นสาเหตุของปัญหาหรือไม่
Olivier Pons

กระบวนการที่อยู่ด้านหลังเป็นปัญหา แต่nohupไม่ใช่ปัญหาโดยตรงที่นี่เนื่องจากไม่มีเทอร์มินัลที่ฝั่งเซิร์ฟเวอร์: ฉันคิดว่าผู้ร้ายเป็นตัวอธิบายไฟล์ที่เปิดโดยเฉพาะ
Gilles 'หยุดความชั่วร้าย'

ใช่ฉันคิดว่าเป็นปัญหาคุณสามารถลองแสดงความคิดเห็นหรือใช้แฮ็คจากลิงค์ด้านบน
Oleksiy Khilkevich

1

คุณจะต้องฆ่ากระบวนการผู้ปกครองของคุณจากภายในสคริปต์ของคุณ

kill -SIGHUP $PPID


0

ปัญหาน่าจะเป็นบรรทัดต่อไปนี้

./qaswvd &

คำสั่งนี้อาจยังคงทำงานอยู่และจะเปิด ssh pipe ไว้จนกว่า stdin และ stdout & stderr จะถูกปิด

ใช้สิ่งนี้แทน:

./qaswvd </dev/null >/dev/null 2>&1 &
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.