1# $NetBSD: var-op-shell.mk,v 1.8 2024/01/05 23:36:45 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.
7OUTPUT!=	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.
21OUTPUT!=	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: "echo "failed"; false" returned non-zero status
32OUTPUT!=	echo "failed"; false
33.if ${OUTPUT} != "failed"
34.  error
35.endif
36
37# A command with empty output may fail as well.
38# expect+1: warning: "false" returned non-zero status
39OUTPUT!=	false
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.
46OUTPUT!=	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.
53OUTPUT!=	echo "before"; false; 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
62OUTPUT!=	kill $$$$
63.if ${OUTPUT} != ""
64.  error
65.endif
66
67# A nonexistent command produces a non-zero exit status.
68# expect+1: warning: "/bin/no/such/command" returned non-zero status
69OUTPUT!=	/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.
75OUTPUT!=	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.
83OUTPUT!=	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
91OUTPUT!=	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'.
98OUTPUT_SHORT!=	echo "$$0"
99OUTPUT_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
112all:
113