Làm thế nào để tôi biết nếu một chương trình đang in ra thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn trong thiết bị đầu cuối?


7

LƯU Ý: một dòng mới xuất hiện nhưng od -c không hiển thị nó.

Lệnh trạng thái của trình phát nhạc của tôi ( quodlibet --status | od -c) có ba trạng thái và tôi đang cố gắng viết một điều kiện dựa trên đầu ra đó. Các đầu ra từ lệnh đó là như thế này (có thể khác nhau tùy thuộc vào cấu hình).

  1. Tôi nghĩ rằng đây là in ra stderr vì od -ckhông hiển thị đúng, mặc dù nó thực hiện cho các lệnh khác.

    not-running
    0000000
    
  2. tạm dừng

    0000000   p   a   u   s   e   d       P   a   n   e   d   B   r   o   w
    0000020   s   e   r       1   .   0   0   0       s   h   u   f   f   l
    0000040   e       o   n       0   .   2   2   8  \n
    0000053
    
  3. đang chơi

    0000000   p   l   a   y   i   n   g       P   a   n   e   d   B   r   o
    0000020   w   s   e   r       1   .   0   0   0       s   h   u   f   f
    0000040   l   e       o   n       0   .   2   3   2  \n
    0000054
    

Mục tiêu của tôi là loại bỏ mọi thứ trừ "không chạy", "tạm dừng" hoặc "chơi" và sử dụng nó trong một điều kiện, như thế này:

#!/bin/bash

status=$(quodlibet --status | awk '{split($0,m," "); printf "%s",m[1]}' | tr -d '\000\007\010\n')
if [ "$status" = "playing" ]; then
  quodlibet --print-playing '<artist>: <title>' | cut -c1-45
else
  echo -n "$status"
fi

Trong trường hợp người chơi không chạy mặc dù điều này luôn in một dòng mới trong thiết bị đầu cuối sau khi "không chạy". Ngay cả khi tôi làm một cái gì đó như thế này

echo -n "$(quodlibet --print-playing '<artist>: <title>' | cut -c1-45)"

Nếu tôi dẫn đầu ra đó od -c, tôi sẽ nhận được cùng

not-running
0000000

Điều đó không đúng. Dòng mới không hiển thị, nhưng nó ở trong thiết bị đầu cuối.

Câu hỏi

  • Điều gì gây ra điều này?
  • Là lệnh in thành lỗi tiêu chuẩn khi chương trình không chạy?
  • Làm thế nào tôi có thể xác định điều này?

Câu trả lời:


5

Vài cách để tiếp cận điều này.

  1. hợp nhất các luồng

    Bạn có thể bằng cách vượt qua việc xác định tất cả sự khác biệt với nhau và chỉ cần hợp nhất STDERR và STDOUT.

    Thí dụ

    quodlibet --status 2>&1 | ...
  2. sử dụng grep

    Bạn có thể cắt đầu ra xuống bằng cách sử dụng -o& -Echuyển sang grep.

    Thí dụ

    $ echo "...blah not-running blah..." | grep -Eo "not-running|paused|playing"
    not-running
    
    $ echo "...blah paused blah..." | grep -Eo "not-running|paused|playing"
    paused
    
    $ echo "...blah playing blah..." | grep -Eo "not-running|paused|playing"
    playing
    

    Điều này sẽ cắt mọi thứ trừ các chuỗi khớp với đối số regex grep.

  3. xác định loại của luồng

    Bạn có thể sử dụng công -ttắc để xác định loại luồng mô tả tệp.

    đoạn trích từ trang Bash của người đàn ông

    -t fd Đúng nếu mô tả tập tin fd đang mở và tham chiếu đến một thiết bị đầu cuối.

    trong đó fd là một trong:

    0: stdin
    1: tiêu chuẩn
    2: thiết bị xuất chuẩn

    Thí dụ

    Điều này phát hiện nếu đầu ra đến từ STDOUT.

    $ if [ -t 1 ]; then echo "from STDOUT"; fi
    from STDOUT
    

    Trả về "từ STDOUT" vì đầu ra đang đi qua trong khi:

    $ (if [ -t 1 ]; then echo "from STDOUT"; fi) | cat

    Trả về không có gì, vì đầu ra đang được hướng đến cat.


hợp nhất các luồng đã làm điều đó. Tôi nghĩ rằng nó là một cái gì đó như thế nhưng tôi không thể hoàn toàn đúng cú pháp.
Michael A
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.