1*6a7405f5SSimon J. Gerraty# $NetBSD: var-op-shell.mk,v 1.11 2025/01/11 21:21:33 rillig Exp $ 22c3632d1SSimon J. Gerraty# 32c3632d1SSimon J. Gerraty# Tests for the != variable assignment operator, which runs its right-hand 42c3632d1SSimon J. Gerraty# side through the shell. 52c3632d1SSimon J. Gerraty 6e2eeea75SSimon J. Gerraty# The variable OUTPUT gets the output from running the shell command. 7e2eeea75SSimon J. GerratyOUTPUT!= echo "success"'ful' 8e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "successful" 9e2eeea75SSimon J. Gerraty. error 10e2eeea75SSimon J. Gerraty.endif 11e2eeea75SSimon J. Gerraty 12e2eeea75SSimon J. Gerraty# Since 2014-08-20, the output of the shell command may be empty. 13e2eeea75SSimon J. Gerraty# 14e2eeea75SSimon J. Gerraty# On 1996-05-29, when the '!=' assignment operator and Cmd_Exec were added, 15e2eeea75SSimon J. Gerraty# an empty output produced the error message "Couldn't read shell's output 16e2eeea75SSimon J. Gerraty# for \"%s\"". 17e2eeea75SSimon J. Gerraty# 189f45a3c8SSimon J. Gerraty# The error message is still in Cmd_Exec but reserved for technical errors. 19e2eeea75SSimon J. Gerraty# It may be possible to trigger the error message by killing the shell after 20e2eeea75SSimon J. Gerraty# reading part of its output. 21e2eeea75SSimon J. GerratyOUTPUT!= true 22e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "" 23e2eeea75SSimon J. Gerraty. error 24e2eeea75SSimon J. Gerraty.endif 25e2eeea75SSimon J. Gerraty 26e2eeea75SSimon J. Gerraty# The output of a shell command that failed is processed nevertheless. 279f45a3c8SSimon J. Gerraty# Unlike the other places that run external commands (expression modifier 289f45a3c8SSimon J. Gerraty# '::!=', expression modifier ':!...!'), a failed command generates only a 299f45a3c8SSimon J. Gerraty# warning, not an "error". These "errors" are ignored in default mode, for 309f45a3c8SSimon J. Gerraty# compatibility, but not in lint mode (-dL). 3122619282SSimon J. Gerraty# expect+1: warning: Command "echo "failed"; (exit 13)" exited with status 13 3222619282SSimon J. GerratyOUTPUT!= echo "failed"; (exit 13) 33e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "failed" 34e2eeea75SSimon J. Gerraty. error 35e2eeea75SSimon J. Gerraty.endif 36e2eeea75SSimon J. Gerraty 37e2eeea75SSimon J. Gerraty# A command with empty output may fail as well. 3822619282SSimon J. Gerraty# expect+1: warning: Command "exit 13" exited with status 13 3922619282SSimon J. GerratyOUTPUT!= exit 13 40e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "" 41e2eeea75SSimon J. Gerraty. error 42e2eeea75SSimon J. Gerraty.endif 43e2eeea75SSimon J. Gerraty 44e2eeea75SSimon J. Gerraty# In the output of the command, each newline is replaced with a space. 45e2eeea75SSimon J. Gerraty# Except for the very last one, which is discarded. 46e2eeea75SSimon J. GerratyOUTPUT!= echo "line 1"; echo "line 2" 47e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "line 1 line 2" 48e2eeea75SSimon J. Gerraty. error 49e2eeea75SSimon J. Gerraty.endif 50e2eeea75SSimon J. Gerraty 51e2eeea75SSimon J. Gerraty# A failing command in the middle results in the exit status 0, which in the 52e2eeea75SSimon J. Gerraty# end means that the whole sequence of commands succeeded. 5322619282SSimon J. GerratyOUTPUT!= echo "before"; (exit 13); echo "after" 54e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "before after" 55e2eeea75SSimon J. Gerraty. error 56e2eeea75SSimon J. Gerraty.endif 57e2eeea75SSimon J. Gerraty 58dba7b0efSSimon J. Gerraty# This should result in a warning about "exited on a signal". 59dba7b0efSSimon J. Gerraty# This used to be kill -14 (SIGALRM), but that stopped working on 60dba7b0efSSimon J. Gerraty# Darwin18 after recent update. 61148ee845SSimon J. Gerraty# expect+1: warning: "kill $$" exited on a signal 62dba7b0efSSimon J. GerratyOUTPUT!= kill $$$$ 63e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "" 64e2eeea75SSimon J. Gerraty. error 65e2eeea75SSimon J. Gerraty.endif 66e2eeea75SSimon J. Gerraty 67e2eeea75SSimon J. Gerraty# A nonexistent command produces a non-zero exit status. 6822619282SSimon J. Gerraty# expect+1: warning: Command "/bin/no/such/command" exited with status 127 69e2eeea75SSimon J. GerratyOUTPUT!= /bin/no/such/command 70e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "" 71e2eeea75SSimon J. Gerraty. error 72e2eeea75SSimon J. Gerraty.endif 73e2eeea75SSimon J. Gerraty 74e2eeea75SSimon J. Gerraty# The output from the shell's stderr is not captured, it just passes through. 75e2eeea75SSimon J. GerratyOUTPUT!= echo "stdout"; echo "stderr" 1>&2 76e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "stdout" 77e2eeea75SSimon J. Gerraty. error 78e2eeea75SSimon J. Gerraty.endif 79e2eeea75SSimon J. Gerraty 80e2eeea75SSimon J. Gerraty# The 8 dollar signs end up as 4 dollar signs when expanded. The shell sees 81e2eeea75SSimon J. Gerraty# the command "echo '$$$$'". The 4 dollar signs are stored in OUTPUT, and 82e2eeea75SSimon J. Gerraty# when that variable is expanded, they expand to 2 dollar signs. 83e2eeea75SSimon J. GerratyOUTPUT!= echo '$$$$$$$$' 84e2eeea75SSimon J. Gerraty.if ${OUTPUT} != "\$\$" 85e2eeea75SSimon J. Gerraty. error 86e2eeea75SSimon J. Gerraty.endif 872c3632d1SSimon J. Gerraty 889f45a3c8SSimon J. Gerraty 899f45a3c8SSimon J. Gerraty# As a debugging aid, log the exact command that is run via the shell. 909f45a3c8SSimon J. Gerraty.MAKEFLAGS: -dv 919f45a3c8SSimon J. GerratyOUTPUT!= echo '$$$$$$$$' 929f45a3c8SSimon J. Gerraty.MAKEFLAGS: -d0 939f45a3c8SSimon J. Gerraty 94d5e0a182SSimon J. Gerraty 95d5e0a182SSimon J. Gerraty# Since main.c 1.607 from 2024-01-05, long shell commands are not run directly 96d5e0a182SSimon J. Gerraty# via '$shell -c $command', they are first written to a temporary file that is 97d5e0a182SSimon J. Gerraty# then fed to the shell via '$shell $tmpfile'. 98d5e0a182SSimon J. GerratyOUTPUT_SHORT!= echo "$$0" 99d5e0a182SSimon J. GerratyOUTPUT_LONG!= echo "$$0" || : ${:U:range=1000} 100d5e0a182SSimon J. Gerraty# When running '$shell -c $command', '$0' in the shell evaluates to the name 101d5e0a182SSimon J. Gerraty# of the shell. 10222619282SSimon J. Gerraty.if ${OUTPUT_SHORT:T} != ${.SHELL:T} 103d5e0a182SSimon J. Gerraty. error 104d5e0a182SSimon J. Gerraty.endif 105d5e0a182SSimon J. Gerraty# When running '$shell $tmpfile', '$0' in the shell evaluates to the name of 106d5e0a182SSimon J. Gerraty# the temporary file. 107d5e0a182SSimon J. Gerraty.if !${OUTPUT_LONG:M*/make*} 108d5e0a182SSimon J. Gerraty. error 109d5e0a182SSimon J. Gerraty.endif 110d5e0a182SSimon J. Gerraty 111d5e0a182SSimon J. Gerraty 112*6a7405f5SSimon J. Gerraty# An undefined expression results in an empty string. 113*6a7405f5SSimon J. Gerraty.MAKEFLAGS: -dv 114*6a7405f5SSimon J. GerratyOUTPUT_OF_UNDEF!= echo x${UNDEF}y 115*6a7405f5SSimon J. Gerraty.if ${OUTPUT_OF_UNDEF} != "xy" 116*6a7405f5SSimon J. Gerraty. error 117*6a7405f5SSimon J. Gerraty.endif 118*6a7405f5SSimon J. Gerraty.MAKEFLAGS: -d0 119*6a7405f5SSimon J. Gerraty 120*6a7405f5SSimon J. Gerraty 1212c3632d1SSimon J. Gerratyall: 122