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