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