ssh và shell qua ssh: làm thế nào để thoát?


22

Tôi đang khởi chạy một tập lệnh xa thông qua SSH như thế này:

ssh user@ipaddress '~/my_script.sh'

Mọi thứ đều ổn nhưng một khi kịch bản kết thúc, kết nối không được đóng lại. Tôi phải nhấn CTRL-C để ngắt kết nối hiện tại.

Tôi đã thử lệnh "exit" trong '~ / my_script.sh' và nó vô dụng. Tôi đã thử lệnh "đăng xuất" trong '~ / my_script.sh' và tôi nhận được một thông báo:

logout: not login shell: use exit

...

Bất kỳ ý tưởng nào tôi có thể làm để đóng SSH tự động và đúng cách khi tập lệnh được thực hiện?

(Sửa đổi để làm rõ :) Đây là những gì bên trong tập lệnh của tôi:

#!/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

Khi tôi khởi chạy nó thông qua SSH, nó chạy và cuối cùng, tôi đọc "Tất cả đã xong". Vì vậy, điều này có nghĩa là nó đạt đến 2 dòng cuối cùng .

Bất kỳ ý tưởng làm thế nào tôi có thể làm để đóng tự động và pr


1
Có gì trong kịch bản?
Ignacio Vazquez-Abrams

@Olivier: Bạn có chuyển tiếp bất kỳ cổng nào (bao gồm cả đại lý và X) không? Kết nối ssh bị đóng khi lệnh kết thúc và tất cả các kết nối TCP đã bị đóng.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: Không, tôi chỉ tạo một liên kết shell để chạy một kịch bản, không có gì được chuyển tiếp.
Olivier Pons

1
@Olivier: Nếu bạn có ~/.ssh/config, hãy thử mà không có nó và vượt qua các tùy chọn -a -x(và không -o) sshđể đảm bảo không có chuyển tiếp nào đang diễn ra. Nếu nó vẫn không hoạt động, hiển thị nội dung của tập lệnh.
Gilles 'SO- ngừng trở nên xấu xa'

@Olivier: kịch bản có bắt đầu bất kỳ công việc nền nào mà nó có thể đang chờ không? Thật không may, các công việc dường như không trả lại bất cứ điều gì khi trong một kịch bản ssh. Ví dụ: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'sẽ liệt kê các tệp, hiển thị xong và đợi 10 giây trước khi quay lại.
asoundmove

Câu trả lời:


19

Lối ra trong tập lệnh shell không hoạt động vì nó thoát khỏi tập lệnh chứ không phải trình bao. Để thoát khỏi shell sau khi script hoàn thành

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

Điều này sẽ chạy tập lệnh sau đó thoát khỏi shell.


3
Nó sẽ được thoát ra. Kịch bản vỏ.
Tạm dừng cho đến khi có thông báo mới.

@Dennis: Nó không hoạt động cho anh ấy vì vậy điều này có thể làm việc thay thế.
Wuffers

2
@Ông. Man: Lệnh của bạn tương đương với bản gốc, ngoại trừ việc nó buộc một lớp vỏ tồn tại giữa sshdvà lớp vỏ đang chạy myscript.sh. Các exitbạn đã viết sẽ hành động khi kịch bản thoát, không giúp được gì. Cách duy nhất để giải pháp của bạn có thể hoạt động là nếu kịch bản làm điều gì đó kỳ quái khi cha mẹ của nó sshdvà không làm điều kỳ quái đó khi cha mẹ của nó là một cái vỏ.
Gilles 'SO- ngừng trở nên xấu xa'

Làm thế nào nó không giúp đỡ? Thoát sẽ đóng vỏ và kết thúc kết nối, đúng không? Và đây không phải là những gì người đăng muốn làm?
Wuffers

3
@MrMan: ~/my_script.sh && exitthoát ngay khi ~/my_script.shthoát. Nếu tập lệnh shell không thoát, lệnh của bạn sẽ không bao giờ nhận được exitbit nào. Vì vậy, nó chỉ là vô dụng.
Gilles 'SO- ngừng trở nên xấu xa'

12

Kết nối ssh vẫn mở khi quá trình bắt đầu bởi ssh (ở đây, shell) thoát, nếu có các tiến trình khác vẫn đang sử dụng nó. Tôi không biết các quy tắc chính xác mà ssh daemon tuân theo, nhưng ít nhất một kết nối đang được sử dụng, nếu đầu ra tiêu chuẩn của bất kỳ tiến trình con nào vẫn được kết nối với đường ống gốc do ssh cung cấp. Đối chiếu:

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

Khi bạn khởi động một daemon, bạn nên đặt nền và đóng mô tả tệp của nó. Ít nhất, sử dụng cái này:

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

Bạn có thể muốn thêm nohupở phía trước; nó sẽ không tạo ra sự khác biệt ở đây nhưng sẽ hữu ích nếu tập lệnh được chạy từ một thiết bị đầu cuối. Nhiều chương trình được thiết kế để hoạt động như daemon có các tùy chọn dòng lệnh để đưa chúng đến ngã ba, đóng mô tả tệp, bỏ qua các tín hiệu và các đặc tính khác. Kiểm tra trong qaswvdtài liệu nếu nó có. Bạn cũng có thể điều tra các tiện ích của da daizerizer.


Có cùng một vấn đề, và điều này làm việc. Câu trả lời được chấp nhận không hoạt động.
Andy

5

Tôi thấy bài đăng này khi tôi tìm kiếm giải pháp cho tình huống tương tự. Mặc dù đã muộn để giải quyết vấn đề của @ Oliver, vì câu trả lời được chấp nhận rõ ràng không hoạt động với OP hoặc tôi (không biết tại sao nó lại được chấp nhận), tôi vẫn muốn đăng giải pháp của riêng mình cho người quản lý tương lai. Thật đơn giản: thêm một -ftùy chọn trong sshlệnh:

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

CHỈNH SỬA

Tác dụng của -ftùy chọn là đặt sshnền, do đó, không có thêm tùy chọn nào được thêm vào, có thể kết nối vẫn còn tồn tại ngay cả khi có vẻ như nó bị hỏng. Người ta có thể tham khảo câu trả lời được đưa ra trong một bài đăng khác trên trang web này nếu quan tâm.


Thận trọng: (-f) này sẽ không hoạt động nếu tập lệnh gốc có (các) lời nhắc cho đầu vào của người dùng.
madD7

3

Giống như Ignacio, tôi tò mò muốn biết những gì trong kịch bản của bạn.

Có lẽ bạn có thể thử và giảm tập lệnh của mình xuống ví dụ nhỏ nhất có thể tạo ra tình trạng lỗi.

Hoặc bắt đầu từ một tập lệnh trống và thêm một lệnh cho đến khi bạn thấy vấn đề, sau đó bạn sẽ biết lệnh nào khiến tập lệnh của bạn bị khóa.

Nếu tập lệnh trống gây ra sự cố cho bạn, bạn có thể muốn điều tra cấu hình ssh của mình, ví dụ, là .bash_logout hoặc một số được gọi như vậy khi thoát có thể gây ra sự cố?


Cảm ơn lời đề nghị của bạn, giờ tôi đã thêm mẫu kịch bản của mình vào câu hỏi của mình.
Olivier Pons

@Olivier: Bạn đã chỉ thêm các phần không liên quan vào tập lệnh của mình. Đăng một tập lệnh (và hướng dẫn sử dụng nếu cần thiết) cho phép người đọc tái tạo vấn đề của bạn . Đơn giản hóa kịch bản càng nhiều càng tốt, nhưng không còn nữa.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Cảm ơn bạn. Tôi đã sửa đổi câu hỏi của mình và thêm toàn bộ kịch bản. Hi vọng điêu nay co ich. Có vẻ như vấn đề có thể là do tôi đang khởi chạy một quá trình nền ( dòng "./qaswvd &" ). Đây có thể là nguồn gốc của vấn đề?
Olivier Pons

1
@Olivier: Có, quy trình chính của bạn sẽ đợi quá trình nền dừng lại trước khi thoát. Nếu bạn muốn một cái gì đó tiếp tục chạy sau khi bạn thoát, bạn có thể muốn thử nohup. Không chắc chắn rằng nó hoạt động với ssh mặc dù, nhưng hãy thử nó sẽ không bị tổn thương.
asoundmove

2

Bạn có thể sử dụng các công việc trong kịch bản của bạn. Nếu đó là vỏ case chỉ chờ công việc của bạn kết thúc và không muốn tự tách ra.

Tôi sẽ không đăng lại, sẽ chuyển tiếp cho bạn http://en.wikipedia.org/wiki/Nohup#Ex hiện_jobs


Tôi đã sửa đổi câu hỏi của mình và thêm toàn bộ kịch bản. Hi vọng điêu nay co ich. Có vẻ như vấn đề có thể là việc tôi đang khởi chạy một quá trình nền (dòng "./qaswvd &"). Nếu bạn đúng, đây có thể là nguồn gốc của vấn đề?
Olivier Pons

Quá trình nền là vấn đề, nhưng nohupkhông trực tiếp là vấn đề ở đây vì không có thiết bị đầu cuối ở phía máy chủ: Tôi nghĩ thủ phạm cụ thể là mô tả tệp mở.
Gilles 'SO- ngừng trở nên xấu xa'

Đúng, tôi nghĩ đó là vấn đề, bạn có thể cố gắng nhận xét hoặc áp dụng hack từ liên kết ở trên
Oleksiy Khilkevich

1

Bạn sẽ cần phải giết quá trình cha mẹ của bạn từ trong tập lệnh của bạn.

kill -SIGHUP $PPID


0

Vấn đề có thể là dòng sau.

./qaswvd &

Lệnh này có thể vẫn đang chạy và sẽ giữ cho ống ssh mở cho đến khi stdin và stdout & stderr được đóng lại.

Sử dụng cái này thay thế:

./qaswvd </dev/null >/dev/null 2>&1 &
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.