Wrapping the call to sqlplus in a shell script seems like the easiest way to do this but could you also call the script using:
sqlplus /NOLOG @test.sql <userid> <pw> <tablespace> empty empty empty
and check inside the script if any of the values are equal to "empty"? That way the script won't hang even if no parameters are passed because you'll still have the three filler parameters.
You could check using something like this: (using && instead of & means you will only be prompted for the value once)
var status number;
set verify on
whenever sqlerror exit 1;
begin
:status := 0;
select decode('&&1','empty',1,:status) into :status from dual;
select decode('&&2','empty',2,:status) into :status from dual;
select decode('&&3','empty',3,:status) into :status from dual;
IF :status != 0 THEN
RAISE_APPLICATION_ERROR (
-20000+-1*:status,'parameter '|| :status || ' is missing');
END IF;
end;
/
The return value when the inputs are invalid will be 1. Without knowing what valid values are for the parameters, it's hard to know which one was omitted.