Lý do bạn không thể gây ra chuyển hướng xảy ra bằng cách mở rộng "$HideErrors"
là các biểu tượng như >
không được xử lý đặc biệt sau khi được tạo ra bởi mở rộng tham số . Điều này thực sự rất tốt, bởi vì các biểu tượng như vậy xuất hiện trong văn bản mà bạn có thể muốn mở rộng và sử dụng theo nghĩa đen.
Điều này giữ cho dù bạn có trích dẫn hay không $HideErrors
. Kết quả của việc mở rộng tham số là đối tượng tách từ và globbing khi mở rộng là không thể viện chứng, nhưng đó là nó.
Đối với những gì phải làm về nó, có rất nhiều cách để đạt được chuyển hướng có điều kiện. Đối với một lệnh rất đơn giản, có thể hợp lý viết toàn bộ lệnh hai lần, một lần trong mỗi nhánh của một case
hoặc if
- else
xây dựng. Điều này sớm trở nên nặng nề, và lệnh bạn đưa ra chắc chắn là một trường hợp không lý tưởng.
Trong số các cách tiếp cận cho phép bạn tránh lặp lại chính mình , có hai cách tôi đặc biệt khuyên dùng, vì chúng khá sạch sẽ và dễ dàng để có được đúng. Bạn muốn sử dụng chỉ một trong số này, không phải cả hai cùng một lúc cho cùng một lệnh và chuyển hướng.
Lưu lệnh thay vì chuyển hướng. Thay vì cố gắng lưu trữ chuyển hướng trong một biến và áp dụng mở rộng tham số, hãy lưu lệnh trong hàm shell . Sau đó viết một case
hoặc if
- else
, trong đó hàm được gọi với chuyển hướng trên một nhánh và không có nó trên nhánh kia.
Nếu bạn khái niệm lệnh của bạn dưới dạng mã mà bạn muốn viết một lần nhưng chạy trong nhiều trường hợp, thì một hàm là giải pháp tự nhiên. Đây là những gì tôi thường làm. Nó có lợi ích của yêu cầu không phải là một subshell cũng không lưu trữ bằng tay và đặt lại của nhà nước.
Với mã của bạn:
launch() {
google-chrome --headless --disable-gpu --dump-dom \
"$RobWebAddress" > "$DownloadName"
}
case $fCron in
true) launch 2>/dev/null;;
*) launch;; # Get silly error messages when running from terminal
esac
Bạn có thể áp dụng bất kỳ khoảng cách nào bạn thích, hoặc if
- else
thay vào đó nếu bạn thích. Lưu ý rằng launch
tự động sử dụng các trình gọi RobWebAddress
và DownloadName
biến, ngay cả khi chúng là biến cục bộ, bởi vì Bash có phạm vi động , không giống như hầu hết các ngôn ngữ lập trình có phạm vi từ vựng.
Chạy lệnh trong một lớp con và áp dụng điều kiện chuyển hướng tới exec
. Đây là những gì Steeldo bình luận , nhưng bên trong (
)
để giữ hiệu ứng cục bộ . Khi các exec
BUILTIN đang chạy không có đối số, nó không thay thế vỏ hiện tại với một quá trình mới, nhưng thay vào đó áp dụng bất kỳ chuyển hướng của nó vào vỏ hiện hành.
(Cũng có thể theo dõi lỗi tiêu chuẩn là gì và khôi phục nó, mà không cần sử dụng một lớp con và do đó không làm mất khả năng sửa đổi môi trường của trình bao hiện tại.
Với mã của bạn:
(
# Suppress silly error messages unless running from terminal
case $fCron in true) exec 2>/dev/null;; esac
google-chrome --headless --disable-gpu --dump-dom \
"$RobWebAddress" > "$DownloadName"
)
Sau khi đóng )
, lỗi tiêu chuẩn có hiệu lực được khôi phục về bất cứ điều gì trước đây, bởi vì nó chỉ thực sự được chuyển hướng trong lớp con chứ không phải trong vỏ cha. Điều này cũng vậy, hoạt động tốt với các biến shell hiện có, vì các subshells có được một bản sao của các biến đó. Mặc dù tôi thích sử dụng hàm shell, tôi thừa nhận phương pháp này có thể yêu cầu ít mã hơn.
Cả hai phương pháp đều hoạt động bất kể lỗi tiêu chuẩn của tệp hoặc thiết bị bắt đầu như thế nào, kể cả trong trường hợp chuyển hướng được áp dụng cho các hàm shell gọi mã chứa hành vi có điều kiện, cũng như trường hợp (được đề cập trong chỉnh sửa của bạn) trong đó lỗi tiêu chuẩn cho toàn bộ tập lệnh đã được chuyển hướng bởi trước đó hoặc . Đường dẫn được tạo ra bởi quá trình thay thế là không có vấn đề.exec 2>&fd
exec 2> path
[[ $fCron == true ]] && exec 2>/dev/null
Thay vào đó, bạn có thể thử