11.1Schristos#!/bin/sh 21.1Schristos# 31.3Skre# $NetBSD: scoped_command,v 1.3 2018/12/04 09:47:25 kre Exp $ 41.1Schristos# 51.1Schristos# Copyright (c) 2014 The NetBSD Foundation, Inc. 61.1Schristos# All rights reserved. 71.1Schristos# 81.1Schristos# This code is derived from software contributed to The NetBSD Foundation 91.1Schristos# by Jarmo Jaakkola. 101.1Schristos# 111.1Schristos# Redistribution and use in source and binary forms, with or without 121.1Schristos# modification, are permitted provided that the following conditions 131.1Schristos# are met: 141.1Schristos# 1. Redistributions of source code must retain the above copyright 151.1Schristos# notice, this list of conditions and the following disclaimer. 161.1Schristos# 2. Redistributions in binary form must reproduce the above copyright 171.1Schristos# notice, this list of conditions and the following disclaimer in the 181.1Schristos# documentation and/or other materials provided with the distribution. 191.1Schristos# 201.1Schristos# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 211.1Schristos# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 221.1Schristos# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 231.1Schristos# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 241.1Schristos# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 251.1Schristos# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 261.1Schristos# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 271.1Schristos# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 281.1Schristos# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 291.1Schristos# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 301.1Schristos# POSSIBILITY OF SUCH DAMAGE. 311.1Schristos# 321.1Schristos 331.2Schristos: ${TEST_SH:=/bin/sh} 341.2Schristos 351.2Schristossane_sh() 361.2Schristos{ 371.2Schristos set -- ${TEST_SH} 381.2Schristos case "$#" in 391.2Schristos (0) set /bin/sh;; 401.2Schristos (1|2) ;; 411.2Schristos (*) set "$1";; # Just ignore options if we cannot make them work 421.2Schristos esac 431.2Schristos 441.2Schristos case "$1" in 451.2Schristos /*) TEST_SH="$1${2+ }$2";; 461.2Schristos ./*) TEST_SH="${PWD}${1#.}${2+ }$2";; 471.2Schristos */*) TEST_SH="${PWD}/$1${2+ }$2";; 481.2Schristos *) TEST_SH="$( command -v "$1" )${2+ }$2";; 491.2Schristos esac 501.2Schristos} 511.2Schristos 521.2Schristossane_sh 531.2Schristos 541.1Schristosset -e 551.1Schristos 561.1Schristos# USAGE: 571.1Schristos# scoped_command scope cmd msg var_suffix 581.1Schristos# 591.1Schristos# Write to stdout a piece of Bourne Shell script with _cmd_ in specific 601.1Schristos# _scope_. The execution of _cmd_ is bracketed by prints of "before _msg_" 611.1Schristos# and "after _msg_, return value ${?}". If the generated script uses 621.1Schristos# variables, __var_suffix_ is appended to their names to allow nesting of 631.1Schristos# scripts generated this way. 641.1Schristos# 651.1Schristos# _scope_ should be one of: case, compound, file, for, func, subshell, 661.1Schristos# until, while. 671.1Schristos# _cmd_ is the command line to execute. Remember proper quoting! 681.1Schristos# _msg_ is text that will be used inside single quotes. 691.1Schristos# _var_suffix_ is a syntactically valid identifier name. 701.1Schristos 711.1Schristos# don't rely on command lists (';') 721.1Schristoscmd="echo 'before ${3}' 731.1Schristos${2} 741.3Skreecho 'after ${3}, return value:' \${?}" 751.1Schristos 761.2Schristosecho "#!${TEST_SH}" 771.1Schristos 781.1Schristos[ 'func' = "${1}" ] && cat <<EOF 791.1Schristosfunc() 801.1Schristos{ 811.1Schristos echo 'before ${3}' 821.1Schristos \${1} 831.1Schristos echo 'after ${3}' 841.1Schristos} 851.1Schristos 861.1Schristosecho 'before function' 871.1Schristosfunc "${2}" "${3}" # don't rely on 'shift' 881.1Schristosecho 'after function' 891.1SchristosEOF 901.1Schristos 911.1Schristos[ 'case' = "${1}" ] && cat <<EOF 921.1Schristosecho 'before case' 931.1Schristoscase 'a' in 941.1Schristos a) ${cmd};; 951.1Schristosesac 961.1Schristosecho 'after case' 971.1SchristosEOF 981.1Schristos 991.1Schristos[ 'file' = "${1}" ] && cat <<EOF 1001.1Schristos${cmd} 1011.1SchristosEOF 1021.1Schristos 1031.1Schristos[ 'while' = "${1}" ] && cat <<EOF 1041.1Schristosecho 'before while' 1051.1Schristoscond_${4}='true true false' 1061.1Schristoswhile \${cond_${4}} 1071.1Schristosdo 1081.1Schristos cond_${4}="\${cond_${4}#* }" 1091.1Schristos ${cmd} 1101.1Schristosdone 1111.1Schristosecho 'after while' 1121.1SchristosEOF 1131.1Schristos 1141.1Schristos[ 'until' = "${1}" ] && cat <<EOF 1151.1Schristosecho 'before until' 1161.1Schristoscond_${4}='false false true' 1171.1Schristosuntil \${cond_${4}} 1181.1Schristosdo 1191.1Schristos cond_${4}="\${cond_${4}#* }" 1201.1Schristos ${cmd} 1211.1Schristosdone 1221.1Schristosecho 'after until' 1231.1SchristosEOF 1241.1Schristos 1251.1Schristos[ 'for' = "${1}" ] && cat <<EOF 1261.1Schristosecho 'before for' 1271.1Schristosfor i_${4} in 1 2 1281.1Schristosdo 1291.1Schristos ${cmd} 1301.1Schristosdone 1311.1Schristosecho 'after for' 1321.1SchristosEOF 1331.1Schristos 1341.1Schristos[ 'subshell' = "${1}" ] && cat <<EOF 1351.1Schristos( 1361.1Schristos echo 'subshell start' 1371.1Schristos ${cmd} 1381.1Schristos echo 'subshell end' 1391.1Schristos) 1401.1SchristosEOF 1411.1Schristos 1421.1Schristos[ 'compound' = "${1}" ] && cat <<EOF 1431.1Schristos{ 1441.1Schristos echo 'compound start' 1451.1Schristos ${cmd}; 1461.1Schristos echo 'compound end' 1471.1Schristos} 1481.1SchristosEOF 1491.1Schristos 1501.1Schristosexit 0 151