---
title: Test commands directly instead of reading $? in a bracket test
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Static Code Analysis (SAST) > SAST
  Rules > Test commands directly instead of reading $? in a bracket test
---

# Test commands directly instead of reading $? in a bracket test

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ().
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**ID:** `bash-code-quality/avoid-indirect-exit-code-check`

**Language:** Bash

**Severity:** Notice

**Category:** Code Style

## Description{% #description %}

Writing a command and then testing `$?` in a separate `[`/`[[`/`test` condition is redundant and brittle: another command between them changes `$?`, `set -e` can exit before the check, and `[`/`[[` themselves overwrite `$?` before the branch body runs. It is better to use `if cmd; then`, `if ! cmd; then`, or capturing the output with `if ! out=$(cmd); then` instead of inspecting `$?` in the conditional.

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```bash
#!/bin/bash
make all;
if [ $? -eq 0 ]; then :; fi
if [[ $? -ne 0 ]]; then :; fi
if [ "${?}" -eq 0 ]; then :; fi
test $? -eq 0 && echo bad
/usr/bin/test $? -eq 0
```

## Compliant Code Examples{% #compliant-code-examples %}

```bash
#!/bin/bash
if grep -q pat file; then echo ok; fi
if ! make all; then echo fail; fi
if [ -f "$f" ]; then :; fi
rc=$?
if [ "$rc" -eq 0 ]; then :; fi
echo "status was $?"
if test -n "$file"; then :; fi
/usr/bin/test -f "$path" && echo ok
```
  Seamless integrations. Try Datadog Code SecurityDatadog Code Security 
{% icon name="icon-external-link" /%}
 