xref: /freebsd/contrib/bmake/unit-tests/var-op-shell.mk (revision 6a7405f5a6b639682cacf01e35d561411ff556aa)
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