From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19766 invoked by alias); 29 Aug 2014 01:48:39 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 19039 Received: (qmail 7563 invoked from network); 29 Aug 2014 01:48:35 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-TMN: [MO+Vmw4jLkivVbxn/FPcReGnJMdMltlJxnWqRvkNx24=] X-Originating-Email: [izumi.natsuka@hotmail.com] Message-ID: Date: Fri, 29 Aug 2014 09:40:29 +0800 From: Izumi Natsuka User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: zsh-users@zsh.org Subject: cat as a builtin command Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 29 Aug 2014 01:41:41.0801 (UTC) FILETIME=[620BB190:01CFC32A] 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