Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
cat as a builtin command
- X-seq: zsh-users 19039
- From: Izumi Natsuka <izumi.natsuka@xxxxxxxxxxx>
- To: zsh-users@xxxxxxx
- Subject: cat as a builtin command
- Date: Fri, 29 Aug 2014 09:40:29 +0800
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
Hello, I'm going to write a shell function that provides a basic functionality(print the content of a file or stdin) of cat[0], in order to avoid forking too many process when I call it in a loop[1]. And I have put the following in my zshrc:
cat() {
if [[ $# -le 1 ]] && [[ ${1:0:1} != '-' || ${1} == '-' ]];then
local file
exec {file}<${1:-0}
read -Erd '' -u ${file}
exec {file}>&-
else
command cat $@
fi
}
It works perfectly except when I want to cat a binary file:
$ zstat +size archlinux-2012.09.07-dual.iso
411041792
$ cat archlinux-2012.09.07-dual.iso | wc -c
39
Seems that the file was cut by some special raw bytes. As I don't known how to avoid that I tried to use another method(via sysread):
cat() {
if [[ $# -le 1 ]] && [[ ${1:0:1} != '-' || ${1} == '-' ]];then
local file REPLY
exec {file}<${1:-0}
if [[ -t 1 ]] && [[ $# -eq 0 || ${1} == '-' ]];then
read -Erd '' -u ${file}
else
sysread -i ${file} -o 1 -s $(zstat +size ${1})
fi
exec {file}>&-
else
command cat $@
fi
}
It works with raw files. Unfortunately this method doesn't avoid the use of subshell[2], it doesn't fit my need[1] and also doesn't work when you want to cat a fifo.
Is there any way that can perform the basic functionality of cat without calling external command?
Izumi Natsuka
0: https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html
1: https://www.ohnekontur.de/2013/02/17/making-cat-a-shell-builtin/
2: http://stackoverflow.com/questions/21976606
Messages sorted by:
Reverse Date,
Date,
Thread,
Author