I have a use case where I need to execute bash commands inside an R program. I can send and verify that bash commands are being executed, but for reasons I do not understand, I can't set and use variables. To begin with, a simple command works fine:
$ R
...
> system("ls")
1a.csv 1b.csv 2.csv 3.csv
[1] 0
>
Now moving on to the problem. I've tried as many approaches as I could find, but none seem to work:
> system("TEST_VAR=\"test_val\"")
[1] 127
Warning message:
In system("TEST_VAR=\"test_val\"") : 'TEST_VAR="test_val"' not found
> system("bash -c 'REPORT_S3=report_s3_test_val'")
[1] 0
> system("echo ${REPORT_S3}")
$REPORT_S3
[1] 0
> system('TEST_VAR=test_var')
[1] 127
Warning message:
In system("TEST_VAR=test_var") : 'TEST_VAR=test_var' not found
> Sys.setenv(TEST_VAR = "test_val")
> system("echo $TEST_VAR")
$TEST_VAR
[1] 0
> system("bash -c 'export TEST_VAR=\"test_val\"'")
[1] 0
> system(" echo ${TEST_VAR}")
$TEST_VAR
[1] 0
None of these attempts succeed.
What I need to do is set variables and subsequently use them to create successively more complex commands. This works fine in in bash. But I can't seem to get it to work in R, apparently for the reasons above.
REPORT_S3="s3://xxxxxxxx-reports/r/html/"$RMD_FILE"_"$EMAIL_ADDRESS"_"$CLOUDWATCH_UUID".html"
PRESIGNED_URL=$(aws s3 presign --expires-in 604800 $REPORT_S3)
JSON_STRING='xxxxx"$CLOUDWATCH_UUID"xxxxxxx"$PRESIGNED_URL".....'
echo $JSON_STRING > message.json
echo '{"ToAddresses":["'$EMAIL_ADDRESS'"],"CcAddresses":[],"BccAddresses":[]}' > destination.json
aws ses send-email --from [email protected] --destination file://destination.json --message file://message.json --region ap-southeast-2
Perhaps there any other options for issuing bash commands other than system that would permit easier reuse of the original source bash code?
CodePudding user response:
Environment variables are per process, and each system(..)
call starts a new process. If you define and reference the variable in the same system
call, it works fine:
> system('
var="foo"
echo "The variable is: $var"
')
The variable is: foo
If you put your entire script into a single system(..)
call, instead of trying to run line by line, it should therefore work.
An alternative method is using Sys.setenv
to set the variables in your current R process, so that future system()
calls inherit it:
> Sys.setenv(var = "bar")
> system('echo "The variable is: $var"')
The variable is: bar
Obviously, since Sys.setenv
is an R function, you must use R code to define your variables, and not rely on shell syntax like $(..)
PS: system()
invokes sh
and not bash
, so all the code you pass it should be sh compatible.