Bỏ dấu vết thực thi cho lệnh echo?


29

Tôi đang chạy các kịch bản shell từ Jenkins, khởi động các kịch bản shell với các tùy chọn shebang #!/bin/sh -ex.

Theo Bash Shebang cho người giả? , -x"làm cho vỏ in một dấu vết thực thi", rất phù hợp cho hầu hết các mục đích - ngoại trừ tiếng vang:

echo "Message"

tạo ra đầu ra

+ echo "Message"
Message

đó là một chút dư thừa, và trông hơi lạ. Có cách nào để -xbật không, nhưng chỉ có đầu ra

Message

thay vì hai dòng trên, ví dụ bằng cách thêm tiền tố vào lệnh echo bằng một ký tự lệnh đặc biệt hoặc chuyển hướng đầu ra?

Câu trả lời:


20

Khi bạn ngẩng cao cổ, bạn sẽ dễ dàng quên rằng mục tiêu là thoát khỏi đầm lầy.                   - câu nói phổ biến

Câu hỏi là về echo, và phần lớn các câu trả lời cho đến nay đã tập trung vào cách lén một set +xlệnh. Có một giải pháp trực tiếp, đơn giản hơn nhiều:

{ echo "Message"; } 2> /dev/null

(Tôi thừa nhận rằng tôi có thể đã không nghĩ đến { …; } 2> /dev/null nếu tôi không nhìn thấy nó trong các câu trả lời trước đó.)

Điều này hơi khó khăn, nhưng, nếu bạn có một khối các echolệnh liên tiếp , bạn không cần phải thực hiện từng lệnh một:

{
  echo "The quick brown fox"
  echo "jumps over the lazy dog."
} 2> /dev/null

Lưu ý rằng bạn không cần dấu chấm phẩy khi bạn có dòng mới.

Bạn có thể giảm gánh nặng gõ bằng cách sử dụng ý tưởng mở /dev/nullvĩnh viễn của kenorb trên một bộ mô tả tệp không chuẩn (ví dụ: 3) và sau đó nói 2>&3thay vì 2> /dev/nullmọi lúc.


Bốn câu trả lời đầu tiên tại thời điểm viết bài này đòi hỏi phải làm một điều gì đó đặc biệt (và, trong hầu hết các trường hợp, cồng kềnh) mỗi khi bạn làm một echo. Nếu bạn thực sự muốn tất cả echo các lệnh để loại bỏ dấu vết thực thi (và tại sao bạn lại không?), Bạn có thể làm như vậy trên toàn cầu mà không cần phải trộn nhiều mã. Đầu tiên, tôi nhận thấy rằng các bí danh không được theo dõi:

$ myfunc()
> {
>     date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016  0:00:00 AM           # Happy Halloween!
$ myfunc
+ myfunc                                # Note that function call is traced.
+ date
Mon, Oct 31, 2016  0:00:01 AM
$ myalias
+ date                                  # Note that it doesn’t say  + myalias
Mon, Oct 31, 2016  0:00:02 AM

(Lưu ý rằng đoạn mã sau hoạt động nếu shebang là #!/bin/sh, ngay cả khi /bin/shlà liên kết đến bash. Nhưng, nếu shebang là #!/bin/bash, bạn cần thêm một shopt -s expand_aliaseslệnh để có bí danh hoạt động trong tập lệnh.)

Vì vậy, cho mẹo đầu tiên của tôi:

alias echo='{ set +x; } 2> /dev/null; builtin echo'

Bây giờ, khi chúng tôi nói echo "Message", chúng tôi đang gọi bí danh, không được truy tìm. Bí danh tắt tùy chọn theo dõi, đồng thời chặn thông báo theo dõi khỏi setlệnh (sử dụng kỹ thuật được trình bày trước trong câu trả lời của người dùng ), sau đó thực hiện echolệnh thực tế . Điều này cho phép chúng tôi có được một hiệu ứng tương tự như câu trả lời của người dùng5071535 mà không cần chỉnh sửa mã ở mỗi echo lệnh. Tuy nhiên, chế độ theo dõi lá này đã tắt. Chúng ta không thể đặt một set -xbí danh (hoặc ít nhất là không dễ dàng) vì bí danh chỉ cho phép một chuỗi được thay thế cho một từ; không có phần nào của chuỗi bí danh có thể được đưa vào lệnh sau các đối số (ví dụ "Message":). Vì vậy, ví dụ, nếu tập lệnh chứa

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date

đầu ra sẽ là

+ date
Mon, Oct 31, 2016  0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016  0:00:04 AM           # Note that it doesn’t say  + date

vì vậy bạn vẫn cần bật lại tùy chọn theo dõi sau khi hiển thị (các) thông báo - nhưng chỉ một lần sau mỗi khốiecho lệnh liên tiếp :

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date


Sẽ thật tuyệt nếu chúng ta có thể set -xtự động thực hiện sau một echo- và chúng ta có thể, với một chút mánh khóe hơn. Nhưng trước khi tôi trình bày điều đó, hãy xem xét điều này. OP đang bắt đầu với các tập lệnh sử dụng #!/bin/sh -exshebang. Ngẫu nhiên người dùng có thể xóa xkhỏi shebang và có một tập lệnh hoạt động bình thường, không có dấu vết thực thi. Sẽ thật tốt nếu chúng ta có thể phát triển một giải pháp giữ lại tài sản đó. Một vài câu trả lời đầu tiên ở đây thất bại với tài sản đó bởi vì họ lần lượt truy tìm lại echomối quan hệ của Google sau khi tuyên bố, vô điều kiện, không liên quan đến việc nó đã được bật hay chưa.  Câu trả lời này rõ ràng không nhận ra vấn đề đó, vì nó thay thế echođầu ra với đầu ra theo dõi; do đó, tất cả các tin nhắn sẽ biến mất nếu tắt theo dõi. Bây giờ tôi sẽ trình bày một giải pháp bật lại dấu vết sau một echocâu lệnh một cách có điều kiện - chỉ khi nó đã được bật. Việc hạ cấp điều này thành một giải pháp giúp truy tìm lại mối quan hệ của Google một cách vô điều kiện là chuyện nhỏ và bị bỏ lại như một bài tập.

alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
        builtin echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}

$-là danh sách tùy chọn; ghép các chữ cái tương ứng với tất cả các tùy chọn được đặt. Ví dụ: nếu các tùy chọn exđược đặt, thì đó $-sẽ là một mớ chữ cái bao gồm ex. Bí danh mới của tôi (ở trên) lưu giá trị của $-trước khi tắt truy tìm. Sau đó, với dấu vết bị tắt, nó ném điều khiển vào một hàm shell. Hàm đó thực hiện echo và sau đó kiểm tra xem liệu xtùy chọn đã được bật khi bí danh được gọi hay chưa. Nếu tùy chọn được bật, chức năng sẽ bật lại; nếu nó bị tắt, chức năng sẽ tắt nó.

Bạn có thể chèn bảy dòng trên (tám, nếu bạn bao gồm một shopt) ở đầu tập lệnh và để phần còn lại một mình.

Điều này sẽ cho phép bạn

  1. để sử dụng bất kỳ dòng shebang nào sau đây:
    #! / bin / sh -ex
    #! / bin / sh -e
    #! / bin / shTHERx
    hoặc chỉ đơn giản
    #! / thùng / sh
    và nó sẽ hoạt động như mong đợi.
  2. để có mã như
    (shebang) 
    lệnh 1
     lệnh 2
     lệnh 3
    đặt -x
    lệnh 4
     lệnh 5
     lệnh 6
    đặt + x
    lệnh 7
     lệnh 8
     lệnh 9
    • Các lệnh 4, 5 và 6 sẽ được theo dõi - trừ khi một trong số chúng là một echo, trong trường hợp đó, nó sẽ được thực thi nhưng không được theo dõi. (Nhưng ngay cả khi lệnh 5 là một echo, lệnh 6 vẫn sẽ được theo dõi.)
    • Các lệnh 7, 8 và 9 sẽ không được theo dõi. Ngay cả khi lệnh 8 là một echo, lệnh 9 vẫn sẽ không được theo dõi.
    • Các lệnh 1, 2 và 3 sẽ được theo dõi (như 4, 5 và 6) hoặc không (như 7, 8 và 9) tùy thuộc vào việc shebang có bao gồm hay không x.

Tái bút: Tôi đã phát hiện ra rằng, trên hệ thống của mình, tôi có thể bỏ builtintừ khóa trong câu trả lời chính giữa của mình (từ khóa chỉ là bí danh echo). Điều này không đáng ngạc nhiên; bash (1) nói rằng, trong quá trình mở rộng bí danh, chụp

Một từ giống hệt với một bí danh đang được mở rộng không được mở rộng lần thứ hai. Điều này có nghĩa rằng người ta có thể bí danh lsđể ls -F, ví dụ, và bash không cố gắng một cách đệ quy mở rộng văn bản thay thế.

Không quá ngạc nhiên, câu trả lời cuối cùng (câu trả lời echo_and_restore) không thành công nếu builtintừ khóa bị bỏ qua 1 . Nhưng kỳ lạ là nó hoạt động nếu tôi xóa builtinvà chuyển thứ tự:

echo_and_restore() {
        echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'

__________
1  Nó dường như làm phát sinh hành vi không xác định. tôi đã nhìn thấy

  • một vòng lặp vô hạn (có thể là do đệ quy không giới hạn),
  • một /dev/null: Bad addressthông báo lỗi và
  • một bãi chứa lõi.

2
Tôi đã thấy một số trò ảo thuật đáng kinh ngạc được thực hiện với bí danh, vì vậy tôi biết kiến ​​thức của mình chưa đầy đủ. Nếu bất cứ ai cũng có thể trình bày một cách để làm tương đương với echo +x; echo "$*"; echo -xbí danh, tôi muốn xem nó.
G-Man nói 'Tái lập Monica'

11

Tôi đã tìm thấy một giải pháp một phần tại InformIT :

#!/bin/bash -ex
set +x; 
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

đầu ra

set +x; 
shell tracing is disabled here 
+ echo "but is enabled here"
but is enabled here

Thật không may, điều đó vẫn còn vang vọng set +x, nhưng ít nhất sau đó nó im lặng. Vì vậy, nó ít nhất là một giải pháp một phần cho vấn đề.

Nhưng có lẽ có một cách tốt hơn để làm điều này? :)


2

Cách này cải thiện giải pháp của riêng bạn bằng cách loại bỏ set +xđầu ra:

#!/bin/bash -ex
{ set +x; } 2>/dev/null
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

2

Đặt set +xbên trong dấu ngoặc, vì vậy nó sẽ chỉ áp dụng cho phạm vi cục bộ.

Ví dụ:

#!/bin/bash -x
exec 3<> /dev/null
(echo foo1 $(set +x)) 2>&3
($(set +x) echo foo2) 2>&3
( set +x; echo foo3 ) 2>&3
true

sẽ xuất ra:

$ ./foo.sh 
+ exec
foo1
foo2
foo3
+ true

Sửa lỗi cho tôi nếu tôi sai, nhưng tôi không nghĩ rằng set +xbên trong lớp con (hoặc hoàn toàn sử dụng các lớp con) đang làm bất cứ điều gì hữu ích. Bạn có thể loại bỏ nó và nhận được kết quả tương tự. Đó là stderr chuyển hướng đến / dev / null đang thực hiện công việc tạm thời "vô hiệu hóa" dấu vết ... Có vẻ như echo foo1 2>/dev/null, v.v., sẽ hiệu quả và dễ đọc hơn.
Tyler Rick

Có dấu vết trong kịch bản của bạn có thể ảnh hưởng đến hiệu suất. Thứ hai chuyển hướng & 2 đến NULL có thể không giống nhau, khi bạn mong đợi một số lỗi khác.
kenorb

Sửa lỗi cho tôi nếu tôi sai, nhưng trong ví dụ của bạn, bạn đã bật tính năng theo dõi trong tập lệnh của mình (với bash -x) và bạn đã chuyển hướng &2sang null (vì &3đã được chuyển hướng thành null), vì vậy tôi không chắc nhận xét đó có liên quan như thế nào. Có thể chúng ta chỉ cần một ví dụ tốt hơn minh họa quan điểm của bạn, nhưng ít nhất trong ví dụ đã cho, có vẻ như nó có thể được đơn giản hóa mà không mất bất kỳ lợi ích nào.
Tyler Rick

1

Tôi yêu câu trả lời toàn diện và được giải thích rõ ràng của g-man , và coi đó là câu trả lời tốt nhất được cung cấp cho đến nay. Nó quan tâm đến bối cảnh của tập lệnh và không bắt buộc cấu hình khi không cần thiết. Vì vậy, nếu bạn đang đọc câu trả lời này trước tiên hãy tiếp tục và kiểm tra xem câu trả lời đó, tất cả công đức đều ở đó.

Tuy nhiên, trong câu trả lời đó có một phần quan trọng bị thiếu: phương pháp được đề xuất sẽ không hoạt động đối với trường hợp sử dụng thông thường, tức là lỗi báo cáo:

COMMAND || echo "Command failed!"

Do cách thức bí danh được xây dựng, điều này sẽ mở rộng sang

COMMAND || { save_flags="$-"; set +x; } 2>/dev/null; echo_and_restore "Command failed!"

và bạn đoán nó, echo_and_restoređược thực hiện luôn , vô điều kiện. Cho rằng set +xphần không chạy, điều đó có nghĩa là nội dung của chức năng đó cũng sẽ được in.

Thay đổi cái cuối cùng ;thành &&không hoạt động, bởi vì trong Bash, ||&&liên kết trái .

Tôi tìm thấy một sửa đổi hoạt động cho trường hợp sử dụng này:

echo_and_restore() {
    echo "$(cat -)"
    case "$save_flags" in
        (*x*) set -x
    esac
}
alias echo='({ save_flags="$-"; set +x; } 2>/dev/null; echo_and_restore) <<<'

Nó sử dụng một lớp con ( (...)phần) để nhóm tất cả các lệnh và sau đó chuyển chuỗi đầu vào qua stdin dưới dạng Chuỗi ở đây ( <<<thứ) sau đó được in bằng cat -. Đây -là tùy chọn, nhưng bạn biết, " rõ ràng là tốt hơn ngầm định ".

Bạn cũng có thể sử dụng cat -trực tiếp mà không có tiếng vang , nhưng tôi thích cách này vì nó cho phép tôi thêm bất kỳ chuỗi nào khác vào đầu ra. Ví dụ, tôi có xu hướng sử dụng nó như thế này:

BASENAME="$(basename "$0")"  # Complete file name
...
echo "[${BASENAME}] $(cat -)"

Và bây giờ nó hoạt động rất đẹp:

false || echo "Command failed"
> [test.sh] Command failed

0

Dấu vết thực thi đi đến stderr, lọc theo cách này:

./script.sh 2> >(grep -v "^+ echo " >&2)

Một số giải thích, từng bước:

  • stderr được chuyển hướng từ - 2>
  • Sầu đến một mệnh lệnh. ->(…)
  • grep là chỉ huy
  • Cận cảnh đòi hỏi phải bắt đầu dòng - ^
  • ... để được theo sau bởi + echo...
  • Sau đó, grepđảo ngược trận đấu --v
  • Càng và điều đó loại bỏ tất cả các dòng bạn không muốn.
  • Kết quả thường sẽ đi đến stdout; chúng tôi chuyển hướng nó đến stderrnơi nó thuộc về. ->&2

Vấn đề là (tôi đoán) giải pháp này có thể đồng bộ hóa các luồng. Bởi vì việc lọc stderrcó thể hơi muộn so với stdout(nơi echođầu ra thuộc về mặc định). Để khắc phục, bạn có thể tham gia các luồng đầu tiên nếu bạn không có cả hai trong stdout:

./script.sh > >(grep -v "^+ echo ") 2>&1

Bạn có thể xây dựng bộ lọc như vậy vào chính tập lệnh nhưng cách tiếp cận này có xu hướng không đồng bộ hóa chắc chắn (nghĩa là nó đã xảy ra trong các thử nghiệm của tôi: dấu vết thực thi của lệnh có thể xuất hiện sau đầu ra ngay sau đó echo).

Mã trông như thế này:

#!/bin/bash -x

{
 # original script here
 # …
} 2> >(grep -v "^+ echo " >&2)

Chạy nó mà không có bất kỳ thủ thuật:

./script.sh

Một lần nữa, sử dụng > >(grep -v "^+ echo ") 2>&1để duy trì đồng bộ hóa với chi phí tham gia các luồng.


Cách tiếp cận khác. Bạn nhận được "một chút dư thừa" và đầu ra trông lạ vì thiết bị đầu cuối của bạn trộn lẫn stdoutstderr . Hai dòng này là động vật khác nhau cho một lý do. Kiểm tra nếu phân tích stderrchỉ phù hợp với nhu cầu của bạn; loại bỏ stdout:

./script.sh > /dev/null

Nếu trong kịch bản của bạn có một echothông báo gỡ lỗi / lỗi in stderrthì bạn có thể thoát khỏi sự dư thừa theo cách được mô tả ở trên. Lệnh đầy đủ:

./script.sh > /dev/null 2> >(grep -v "^+ echo " >&2)

Lần này chúng tôi chỉ làm việc với nhau stderr, vì vậy việc đồng bộ hóa không còn là vấn đề đáng lo ngại nữa. Thật không may, theo cách này, bạn sẽ không thấy dấu vết cũng như đầu ra của echobản in đó stdout(nếu có). Chúng tôi có thể cố gắng xây dựng lại bộ lọc của mình để phát hiện chuyển hướng ( >&2) nhưng nếu bạn nhìn vào echo foobar >&2, echo >&2 foobarecho "foobar >&2"sau đó bạn có thể sẽ đồng ý rằng mọi thứ trở nên phức tạp.

Rất nhiều phụ thuộc vào tiếng vang bạn có trong (các) kịch bản của bạn. Hãy suy nghĩ hai lần trước khi bạn thực hiện một số bộ lọc phức tạp, nó có thể phản tác dụng. Tốt hơn là có một chút dư thừa hơn là vô tình bỏ lỡ một số thông tin quan trọng.


Thay vì loại bỏ dấu vết thực thi của một, echochúng ta có thể loại bỏ đầu ra của nó - và bất kỳ đầu ra nào ngoại trừ dấu vết. Để chỉ phân tích dấu vết thực hiện, hãy thử:

./script.sh > /dev/null 2> >(grep "^+ " >&2)

Hoàn hảo? Không. Hãy nghĩ điều gì sẽ xảy ra nếu có echo "+ rm -rf --no-preserve-root /" >&2trong kịch bản. Ai đó có thể bị đau tim.


Và cuối cùng…

May mắn thay có BASH_XTRACEFDbiến môi trường. Từ man bash:

BASH_XTRACEFD
Nếu được đặt thành một số nguyên tương ứng với một bộ mô tả tệp hợp lệ, bash sẽ ghi đầu ra theo dõi được tạo khi set -xđược bật cho bộ mô tả tệp đó.

Chúng ta có thể sử dụng nó như thế này:

(exec 3>trace.txt; BASH_XTRACEFD=3 ./script.sh)
less trace.txt

Lưu ý dòng đầu tiên sinh ra một subshell. Bằng cách này, bộ mô tả tệp sẽ không còn hiệu lực cũng như biến được gán trong trình bao hiện tại sau đó.

Nhờ BASH_XTRACEFDbạn có thể phân tích dấu vết không có tiếng vang và bất kỳ đầu ra nào khác, bất kể chúng có thể là gì. Đó không phải là chính xác những gì bạn muốn nhưng phân tích của tôi làm cho tôi nghĩ rằng đây là (nói chung) Đúng cách.

Tất nhiên bạn có thể sử dụng một phương pháp khác, đặc biệt là khi bạn cần phân tích stdoutvà / hoặc stderrcùng với dấu vết của bạn. Bạn chỉ cần nhớ có những hạn chế và cạm bẫy nhất định. Tôi đã cố gắng thể hiện (một số) chúng.


0

Trong Makefile bạn có thể sử dụng @biểu tượng.

Cách sử dụng ví dụ: @echo 'message'

Từ tài liệu GNU này :

Khi một dòng bắt đầu bằng '@', tiếng vang của dòng đó bị triệt tiêu. '@' Bị loại bỏ trước khi dòng được chuyển đến trình bao. Thông thường, bạn sẽ sử dụng lệnh này cho một lệnh có tác dụng duy nhất là in một cái gì đó, chẳng hạn như lệnh echo để chỉ ra tiến trình thông qua tệp thực hiện.


Xin chào, tài liệu bạn tham khảo là dành cho gnu make, không phải shell. Bạn có chắc chắn nó hoạt động? Tôi nhận được lỗi ./test.sh: line 1: @echo: command not found, nhưng tôi đang sử dụng bash.

Wow, xin lỗi tôi hoàn toàn đọc sai câu hỏi. Có, @chỉ hoạt động khi bạn đang lặp lại trong makefiles.
derek

@derek Tôi đã chỉnh sửa câu trả lời ban đầu của bạn để bây giờ nói rõ rằng giải pháp chỉ giới hạn cho Makefiles. Tôi đã thực sự tìm kiếm cái này, vì vậy tôi muốn bình luận của bạn không có tiếng xấu. Hy vọng, mọi người sẽ thấy nó hữu ích quá.
Shakaron

-1

Đã chỉnh sửa ngày 29 tháng 10 năm 2016 cho mỗi đề xuất của người điều hành rằng bản gốc không chứa đủ thông tin để hiểu những gì đang xảy ra.

"Thủ thuật" này chỉ tạo ra một dòng đầu ra thông báo tại thiết bị đầu cuối khi xtrace hoạt động:

Câu hỏi ban đầu là Có cách nào để bật -x không, nhưng chỉ xuất Tin nhắn thay vì hai dòng . Đây là một trích dẫn chính xác từ câu hỏi.

Tôi hiểu câu hỏi là, làm thế nào để "bật set -x VÀ tạo một dòng duy nhất cho một tin nhắn"?

  • Theo nghĩa toàn cầu, câu hỏi này về cơ bản là về tính thẩm mỹ - người hỏi muốn tạo ra một dòng duy nhất thay vì hai dòng gần như trùng lặp được tạo ra trong khi xtrace đang hoạt động.

Vì vậy, tóm lại, OP yêu cầu:

  1. Để thiết lập -x có hiệu lực
  2. Tạo một thông điệp, con người có thể đọc được
  3. Chỉ sản xuất một dòng duy nhất của đầu ra tin nhắn.

OP không yêu cầu sử dụng lệnh echo . Họ đã trích dẫn nó như một ví dụ về sản xuất thông điệp, sử dụng chữ viết tắt, ví dụ như viết tắt của tiếng Latin exempli gratia hoặc "ví dụ".

Suy nghĩ "bên ngoài hộp" và từ bỏ việc sử dụng tiếng vang để tạo ra thông điệp, tôi lưu ý rằng một tuyên bố chuyển nhượng có thể đáp ứng tất cả các yêu cầu.

Thực hiện gán chuỗi văn bản (chứa thông báo) cho biến không hoạt động.

Việc thêm dòng này vào tập lệnh không làm thay đổi bất kỳ logic nào, nhưng sẽ tạo ra một dòng duy nhất khi theo dõi được kích hoạt: (Nếu bạn đang sử dụng biến $ echo , chỉ cần thay đổi tên thành một biến không sử dụng khác)

echo="====================== Divider line ================="

Những gì bạn sẽ thấy trên thiết bị đầu cuối chỉ có 1 dòng:

++ echo='====================== Divider line ================='

không phải hai, vì OP không thích:

+ echo '====================== Divider line ================='
====================== Divider line =================

Đây là kịch bản mẫu để chứng minh. Lưu ý rằng việc thay thế biến thành một thông báo (tên thư mục $ HOME 4 dòng từ cuối) hoạt động, vì vậy bạn có thể theo dõi các biến bằng phương pháp này.

#!/bin/bash -exu
#
#  Example Script showing how, with trace active, messages can be produced
#  without producing two virtually duplicate line on the terminal as echo does.
#
dummy="====================== Entering Test Script ================="
if [[ $PWD == $HOME ]];  then
  dummy="*** "
  dummy="*** Working in home directory!"
  dummy="*** "
  ls -la *.c || :
else
  dummy="---- C Files in current directory"
  ls -la *.c || :
  dummy="----. C Files in Home directory "$HOME
  ls -la  $HOME/*.c || :
fi

Và đây là đầu ra từ việc chạy nó trong thư mục gốc, sau đó là thư mục chính.

$ cd /&&DemoScript
+ dummy='====================== Entering Test Script ================='
+ [[ / == /g/GNU-GCC/home/user ]]
+ dummy='---- C Files in current directory'
+ ls -la '*.c'
ls: *.c: No such file or directory
+ :
+ dummy='----. C Files in Home directory /g/GNU-GCC/home/user'
+ ls -la /g/GNU-GCC/home/user/HelloWorld.c /g/GNU-GCC/home/user/hw.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 /g/GNU-GCC/home/user/HelloWorld.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 /g/GNU-GCC/home/user/hw.c
+ dummy=---------------------------------

$ cd ~&&DemoScript
+ dummy='====================== Entering Test Script ================='
+ [[ /g/GNU-GCC/home/user == /g/GNU-GCC/home/user ]]
+ dummy='*** '
+ dummy='*** Working in home directory!'
+ dummy='*** '
+ ls -la HelloWorld.c hw.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 HelloWorld.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 hw.c
+ dummy=---------------------------------

1
Lưu ý, ngay cả phiên bản đã chỉnh sửa của câu trả lời đã xóa của bạn (đây là bản sao), vẫn không trả lời câu hỏi, vì câu trả lời không chỉ xuất ra thông báo mà không có lệnh echo liên quan, đó là những gì OP yêu cầu.
DavidPostill

Lưu ý, câu trả lời này đang được thảo luận trên meta Tôi đã bị phạt vì câu trả lời mà 1 người điều hành không thích?
DavidPostill

@David Tôi đã mở rộng lời giải thích, mỗi bình luận trong diễn đàn meta.
HiTechHiTouch

@David Một lần nữa tôi khuyến khích bạn đọc OP rất cẩn thận, chú ý đến chữ ".eg" trong tiếng Latin. Các poster KHÔNG yêu cầu lệnh echo được sử dụng. OP chỉ tham chiếu echo như một ví dụ (cùng với chuyển hướng) các phương thức tiềm năng để giải quyết vấn đề. Hóa ra bạn cũng không cần,
HiTechHiTouch

Và nếu OP muốn làm một cái gì đó như thế echo "Here are the files in this directory:" *nào?
G-Man nói 'Tái lập Monica'
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.