#!/bin/bash # Bash alternative to external cat call # # Copyright (C) 2014 Mike Gerwitz # # This file is part of pkgsh. # # pkgsh is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # N.B. While this shell implementation may be faster for most use cases, the # external binary will likely be much faster for large streams. # # This also contains some convenience functions that are not part of # GNU coreutils. ## [ -z $__PKGSH_INC_COREUTILS_CAT ] || return __PKGSH_INC_COREUTILS_CAT=1 ## # Echo characters from stdin up to (but not including) the provided # delimiter cat-until() { local -r delim="${1?Missing terminating delimiter}" local -r file="${2:-/dev/stdin}" read -rd "$delim" < "$file" local -ri result=$? echo -n "$REPLY" return $result } ## # Echo characters from stdin up to and including the provided delimiter cat-until-incl() { # `cat-until` will validate local -r delim="$1" cat-until "$@" \ && echo -n "$delim" } ## # Proxies to either the shell implementation of cat or the system binary, # depending on support cat() { [[ "$1" =~ ^-[^-\ ] ]] \ && command cat "$@" \ || quickcat "$@" } ## # Limited implementation of `cat` for performance # # TODO: The proper research has not yet gone into optimizing this; this is # just an initial implementation to get things going. I will be addressing # this shortly. # # TODO: Exit status. quickcat() { local in="${1:-/dev/stdin}" [ "$in" == - ] && in=/dev/stdin readonly in while true; do IFS= read -r || { echo -n "$REPLY" break } echo "$REPLY" done < "$in" if shift && [ $# -ne 0 ]; then quickcat "$@" fi }