Làm thế nào tôi có thể đăng nhập đầy đủ tất cả các hành động bash script?


44

Tôi muốn chụp TẤT CẢ dữ liệu nhật ký, cả hai đều có thông báo lỗi, từ đầu ra tập lệnh của tôi và chuyển hướng tất cả chúng sang tệp nhật ký.

Tôi có kịch bản như dưới đây:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Tôi muốn xem tất cả các hành động trong tập tin /home/scripts/cron/logs

Nhưng tôi chỉ thấy những gì tôi đặt sau lệnh echo.

Làm thế nào để kiểm tra nhật ký là lệnh SSH đã thành công?

Tôi cần phải thu thập tất cả các dữ liệu nhật ký. Tôi cần điều này để theo dõi kết quả của mọi lệnh trong kịch bản của tôi, để phân tích tốt hơn những gì đang diễn ra trong khi kịch bản thất bại.


Bạn cũng có thể sử dụng "tập lệnh" để thực hiện điều này. Xem bài đăng này: [tại đây] [1] [1]: stackoverflow.com/questions/5985060/iêu
xX0v0Xx

bạn phải cẩn thận với errexit - Tôi nhận thấy nó bị bỏ qua hoặc lỗi không thoát khỏi tập lệnh, vd. nếu bạn có một cái gì đó như thế này trong kịch bản: lệnh | | dosmthg khi lệnh thất bại tập lệnh không thoát ngay lập tức với tập errexit mà chỉ chạy dosmthg và tiếp tục tập lệnh

Câu trả lời:


67

Tôi thường đặt một cái gì đó tương tự như sau vào đầu mỗi tập lệnh (đặc biệt là nếu nó sẽ chạy như một daemon):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Giải trình:

  1. exec 3>&1 4>&2

    Lưu mô tả tệp để chúng có thể được khôi phục thành bất cứ thứ gì trước khi chuyển hướng hoặc sử dụng chính chúng để xuất ra bất cứ thứ gì chúng có trước khi chuyển hướng sau.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Khôi phục mô tả tập tin cho các tín hiệu cụ thể. Nói chung không cần thiết vì chúng nên được khôi phục khi thoát khỏi lớp vỏ phụ.

  3. exec 1>log.out 2>&1

    Chuyển hướng stdoutđến tập tin log.outsau đó chuyển hướng stderrđến stdout. Lưu ý rằng thứ tự là quan trọng khi bạn muốn chúng đi đến cùng một tệp. stdout phải được chuyển hướng trước khi stderrđược chuyển hướng đến stdout.

Từ đó trở đi, để xem đầu ra trên bàn điều khiển (có thể), bạn chỉ cần chuyển hướng đến &3. Ví dụ,

echo "$(date) : part 1 - start" >&3

sẽ đi đến bất cứ nơi nào stdoutđược chỉ dẫn, có lẽ là bàn điều khiển, trước khi thực hiện dòng 3 ở trên.


<< đẹp hơn, Cảm ơn! Tôi đã thêm các threelines (exec, bẫy, exec) vào đầu kịch bản và tôi có thể nhận được cả stdout và stderr. Nhưng một vấn đề: Tôi đã thấy "Mô tả tệp 3 (pipe: XXX) bị rò rỉ trên some_command" ... Vui lòng cho tôi biết làm thế nào tôi có thể tránh bị các lỗi này. Tôi sử dụng busybox dựa trên sh trong bảng tùy chỉnh.
kumar

3
KungFu tuyệt vời đây !!! - Thậm chí tốt hơn là sử dụng trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Bộ mô tả tập tin khôi phục giả mã RETURN mỗi lần một hàm shell hoặc tập lệnh được thực thi với. hoặc nguồn dựng sẵn kết thúc thực thi. Vì điều này (và vì những lý do khác) trong các tập lệnh của tôi, tôi thêm vào như 2 dòng cuối cùng: return& exit 0- Chỉ 2 xu của tôi, danh tiếng cho bạn @nicerobot!
DavAlPi

Có rất nhiều chi tiết về việc đăng nhập các kịch bản shell thông qua các biến thể toàn cầu của shell. Chúng tôi có thể mô phỏng loại đăng nhập tương tự trong tập lệnh shell: cubrace.com/2016/03/ffic-logging-mechnism-in-shell.html Bài đăng có chi tiết về các mức ghi nhật ký giới thiệu như INFO, DEBUG, ERROR. Chi tiết theo dõi như nhập tập lệnh, thoát tập lệnh, nhập chức năng, thoát chức năng.
Piyush Chordia

Việc liệt kê các traptín hiệu trông hơi kỳ lạ. Thông thường bạn sẽ muốn bao gồm 15là tốt.
tripleee 4/11/2016


14

để có được đầu ra ssh cho logfile của bạn, bạn phải chuyển hướng stderrđến stdout. bạn có thể làm điều này bằng cách nối thêm 2>&1sau tập lệnh bash của bạn.

Nó sẽ giống như thế này:

#!/bin/bash
(
...
) 2>&1 | tee ...

khi điều này không hiển thị các mesages theo đúng thứ tự, hãy thử thêm một subshell khác:

#!/bin/bash
((
...
) 2>&1) | tee ...

1
Điều này làm việc tuyệt vời. Trên thực tế, bạn có thể điều khiển cả thiết bị xuất chuẩn và thiết bị xuất chuẩn với:( ... ) |& tee output.log
Noam Manos

13

Khi tôi đọc câu hỏi của bạn, bạn không muốn đăng nhập đầu ra, nhưng toàn bộ chuỗi lệnh, trong trường hợp đó, các câu trả lời khác sẽ không giúp bạn.

Gọi các kịch bản shell với -x để xuất mọi thứ:

sh -x foo.sh

Đăng nhập vào tập tin bạn muốn với:

sh -x foo.sh >> /home/scripts/cron/logs


2
Tùy chọn +1 cho -x
Coc

10

Trong bash, bạn có thể đặt set -xvà nó sẽ in ra mọi lệnh mà nó thực thi (và các biến bash) sau đó. Bạn có thể tắt nó với set +x.

Nếu bạn muốn bị hoang tưởng, bạn có thể đưa set -o errexitvào kịch bản của mình. Điều này có nghĩa là tập lệnh sẽ thất bại và dừng lại nếu một lệnh trả về mã thoát khác không, đó là cách tiêu chuẩn unix để báo hiệu rằng đã xảy ra sự cố.

Nếu bạn muốn có được các bản ghi đẹp hơn, bạn nên xem tstrong moreutilsgói debian / ubfox. Nó sẽ tiền tố mỗi dòng với dấu thời gian và in ra. Vì vậy, bạn có thể thấy khi mọi thứ đang xảy ra.


1
"set -o errexit" phải giống với "set -e"
Ajith Antony

0

Theo những gì người khác nói, hướng dẫn sử dụng là một tài nguyên tốt. Tôi đặt:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Ở đầu các tập lệnh tôi muốn tiếp tục hoặc set -exnếu nó sẽ thoát do lỗi.


Làm thế nào điều này sẽ giúp cho các bản ghi ssh và thực hiện lệnh thành công?
Asktyagi

Thử nghiệm với tập lệnh giả của OP, nó ghi lại từng lệnh và bất kỳ kết quả nào: thời gian chờ ssh, tên miền không chính xác, v.v. Hoặc đối với địa chỉ ssh hợp lệ, nó ghi lại các lệnh trong shell từ xa. Nếu cần thêm thông tin về đăng nhập ssh, có lẽ ssh -vv?
rồng951
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.