2012-01-04 27 views
8

Tôi hiện đang sử dụng sau đây để nắm bắt tất cả mọi thứ mà đi đến nhà ga và ném nó vào một tập tin logbash tee remove màu

exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE) 

tuy nhiên, tôi không muốn mã màu thoát/lộn xộn đi vào tệp nhật ký. vì vậy tôi có một cái gì đó như thế này mà sorta làm việc

exec 4<&1 5<&2 1>&2>&>(
    while read -u 0; do 
     #to terminal 
     echo "$REPLY" 
     #to log file (color removed) 
     echo "$REPLY" | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' >> $LOG_FILE 
    done 
    unset REPLY #tidy 
) 

trừ read chờ đợi vận chuyển trở lại mà không phải là lý tưởng đối với một số phần của kịch bản (ví dụ echo -n "..." hoặc printf mà không \n).


Follow-up để trả lời Jonathan Leffler của:

Với ví dụ kịch bản test.sh:

#!/bin/bash 

LOG_FILE="./test.log" 
echo -n >$LOG_FILE 

exec 4<&1 5<&2 1>&2>&>(tee -a >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > $LOG_FILE)) 


##### ##### ##### 
# Main 

echo "starting execution" 
printf "\n\n" 

echo "color test:" 
echo -e "\033[0;31mhello \033[0;32mworld\033[0m!" 
printf "\n\n" 

echo -e "\033[0;36mEnvironment:\033[0m\n foo: cat\n bar: dog\n your wife: hot\n fix: A/C" 
echo -n "Before we get started. Is the above information correct? " 
read YES 
echo -e "\n[READ] $YES" >> $LOG_FILE 
YES=$(echo "$YES" | sed 's/^\s*//;s/\s*$//') 
test ! "$(echo "$YES" | grep -iE '^y(es)?$')" && echo -e "\nExiting... :(" && exit 
printf "\n\n" 

#...some hundreds of lines of code later... 

echo "Done!" 


##### ##### ##### 
# End 

exec 1<&4 4>&- 2<&5 5>&- 

echo "Log File: $LOG_FILE" 
  1. Sản lượng đến thiết bị đầu cuối được như mong đợi và không có mã màu thoát/lộn xộn trong tệp nhật ký như mong muốn. Tuy nhiên, khi kiểm tra test.log, tôi không thấy số [READ] ... (xem dòng 21 của test.sh).

  2. Tệp nhật ký [của tập lệnh bash thực tế] chứa dòng Log File: ... ở cuối của nó ngay cả sau khi đóng các fds 4 và 5. Tôi đã có thể giải quyết vấn đề bằng cách đặt một số sleep 1 trước số exec thứ hai - Tôi cho rằng có một điều kiện chủng tộc hoặc shenanigans fd để đổ lỗi cho nó. Thật không may cho các bạn, tôi không thể tái sản xuất vấn đề này với test.sh nhưng tôi muốn được quan tâm đến bất kỳ đầu cơ bất cứ ai có thể có.

+0

Lưu ý rằng \ e [... m mã cụ thể cho VT100/VT200/etc. và có thể không phải là những chương trình thực sự được xuất bản bởi chương trình trên một loại $ TERM khác. –

Trả lời

3

Xem xét sử dụng các chương trình pee thảo luận trong Is it possible to distribute stdin over parallel processes. Nó sẽ cho phép bạn gửi dữ liệu nhật ký thông qua tập lệnh sed của bạn, trong khi tiếp tục gửi các màu đến đầu ra thực tế.

Một lợi thế lớn của việc này là nó sẽ loại bỏ 'thực thi sed một lần trên mỗi dòng đầu ra nhật ký'; điều đó thực sự mang tính chất khủng khiếp về hiệu suất (về số lượng các quá trình được thực hiện, nếu không có gì khác).

+0

tuyệt vời! cảm ơn bạn! 'exec 4 <&1 5<&2 1> & 2> &> (tee -a> (sed-r 's/\ x1B \ [([0-9] {1,2} (; [0-9] {1,2})?) ? [m | K] // g '> $ LOG_FILE)) ' – Andrew

+0

Vui lòng xem theo dõi – Andrew

1

Tôi biết nó không phải là một giải pháp hoàn hảo, nhưng cat -v sẽ làm cho ký tự không nhìn thấy được như \x1B được chuyển đổi thành dạng có thể nhìn thấy như ^[[1;34m. Đầu ra sẽ lộn xộn, nhưng nó sẽ là văn bản ascii ít nhất.

0

Bạn có thể thử sử dụng tùy chọn -n để đọc. Nó đọc trong n ký tự thay vì chờ đợi một dòng mới. Bạn có thể đặt nó thành một. Điều này sẽ làm tăng số lần lặp lại mã chạy, nhưng nó sẽ không chờ các dòng mới.

Từ người đàn ông:

-n NCHARS read returns after reading NCHARS characters rather than waiting for a complete line of input.

Lưu ý: Tôi đã không kiểm tra này

0

tôi sử dụng để làm công cụ như thế này bằng cách thiết lập TERM=dumb trước khi chạy lệnh của tôi. Điều đó đã loại bỏ khá nhiều ký tự điều khiển ngoại trừ tab, CR và LF. Tôi không có ý tưởng nếu điều này làm việc cho tình hình của bạn, nhưng nó có giá trị một thử. Vấn đề là bạn sẽ không thấy mã hóa màu trên thiết bị đầu cuối của bạn vì nó là một thiết bị đầu cuối câm.

Bạn cũng có thể thử vis hoặc cat (đặc biệt là thông số -v) và xem liệu chúng có làm gì đó cho bạn hay không. Bạn chỉ cần đặt chúng vào đường ống của bạn như thế này:

exec 4<&1 5<&2 1>&2>&>(tee -a | cat -v | $LOG_FILE) 

Bằng cách này, hầu như tất cả các chương trình đầu cuối đều có tùy chọn để nắm bắt đầu vào và làm sạch hầu hết cho bạn. Bạn đang sử dụng nền tảng nào và bạn đang sử dụng loại chương trình đầu cuối nào?

0

Có thể không screen -L hoặc lệnh script là các tùy chọn khả thi thay vì vòng lặp exec này?

+0

của chúng tôi, chúng tôi có thể tắt các ký tự điều khiển bằng' màn hình' không? – Stuart