Tôi tin rằng Ctrl- Ccó thể bị mắc kẹt trong các tập lệnh bash. Có phải cũng có thể nhốt nó bên trong một tập lệnh Awk để xử lý sự kiện đó không?
Ví dụ, để hủy bỏ xử lý, nhưng in kết quả của những gì đã được xử lý, thay vì chỉ bỏ đi?
Tôi tin rằng Ctrl- Ccó thể bị mắc kẹt trong các tập lệnh bash. Có phải cũng có thể nhốt nó bên trong một tập lệnh Awk để xử lý sự kiện đó không?
Ví dụ, để hủy bỏ xử lý, nhưng in kết quả của những gì đã được xử lý, thay vì chỉ bỏ đi?
Câu trả lời:
Tôi không biết về bất kỳ awktriển khai nào có hỗ trợ cho việc đó. Bạn có thể viết một phần mở rộng cho gawkđiều đó , nhưng ở đây, tôi muốn chuyển sang ngôn ngữ khác.
perlgiúp dễ dàng chuyển đổi awkcác tập lệnh với a2ptập lệnh của nó .
Chẳng hạn, nếu bạn có một đoạn awkscript như:
{count[$0]++}
END {
for (i in count) printf "%5d %s\n", count[i], i
}
a2p trên đó sẽ cung cấp cho bạn một cái gì đó như:
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# this emulates #! processing on NIH machines.
# (remove #! line above if indigestible)
eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
# process any FOO=bar switches
while (<>) {
chomp; # strip record separator
$count{$_}++;
}
foreach $i (keys %count) {
printf "%5d %s\n", $count{$i}, $i;
}
Bạn có thể chỉnh sửa để thêm xử lý tín hiệu của mình (và loại bỏ việc xử lý các var=valueđối số mà chúng tôi không muốn ở đây và phần dành cho các hệ thống không hỗ trợ #!):
#!/usr/bin/perl
sub report {
foreach $i (keys %count) {
printf "%5d %s\n", $count{$i}, $i;
}
}
$SIG{INT} = sub {
print STDERR "Interrupted\n";
report;
$SIG{INT} = 'DEFAULT';
kill('INT', $$); # report dying of SIGINT.
};
while (<>) {
chomp; # strip record separator
$count{$_}++;
}
report;
Một cách khác có thể là làm gián đoạn việc cung cấp dữ liệu đến awkvà awkbỏ qua SIGINT, như thay vì:
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}' file
làm:
cat file | (
trap '' INT
awk '{count[$0]++};END{for (i in count) printf "%5d %s\n", count[i], i}'
)
Ctrl+Csau đó sẽ giết catnhưng không được awk. awkvẫn sẽ tiếp tục xử lý đầu vào còn lại vẫn còn trong đường ống.
Để phát hiện Ctrl+Ctrong awk, bạn có thể làm:
(cat file && echo cat terminated normally) | (
trap '' INT
awk '{count[$0]++}
END{
if ($0 == "cat terminated normally") delete count[$0]
else print "Interrupted"
for (i in count) printf "%5d %s\n", count[i], i}'
)