1

The example below shows how if temp_file is made local as part of the same line that mktemp is called then the exit status retrieved using $? is always zero, regardless of whether the command succeeded or failed (mktemp_xyz is used so that it always fails). If temp_file is made local in advance then the $? exit status is as expected.

Can someone explain what is going on here please?

#!/bin/bash

test_1()
{
    local temp_file=$(mktemp_xyz -q -t "test.tmp.XXXXXX")
    local make_temp_file_ret_val=$?

    echo "temp_file: $temp_file"
    echo "make_temp_file_ret_val: $make_temp_file_ret_val"
}

test_2()
{
    local temp_file=""
    temp_file=$(mktemp_xyz -q -t "test.tmp.XXXXXX")
    local make_temp_file_ret_val=$?

    echo "temp_file: $temp_file"
    echo "make_temp_file_ret_val: $make_temp_file_ret_val"
}

test_1
echo ""
test_2

Output is:

$ ./test 
./test: line 6: mktemp_xyz: command not found
temp_file: 
make_temp_file_ret_val: 0

./test: line 16: mktemp_xyz: command not found
temp_file: 
make_temp_file_ret_val: 127

Thanks.

1 Answer 1

4

local is a command itself, not just a modifier to an assignment statement. In test1, you are recording the exit status of the local command, not the command in the command substitution. In test2, you've separated the local command from the assignment to the variable marked as local, so $? contains the exit status you are expecting.


Unrelated, but you don't need to initialize a variable when marking it as local. This works just fine:

local temp_file
temp_file=$(mktemp_xyz -q -t "test.tmp.XXXXXX")

temp_file remains unset until you actually assign a value to it, but the name is local once you actually do assign a value.

Sign up to request clarification or add additional context in comments.

2 Comments

This is shellcheck SC2155. The wiki uses export but the same applies here.
Thanks, that explains it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.