var-op-shell.mk revision 1.9 1 # $NetBSD: var-op-shell.mk,v 1.9 2024/06/30 11:37:21 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} != ${.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 all:
113