Using an environment variable is perfectly OK, however, you don't need to manually set this environment variable yourself. Apache provides the REDIRECT_STATUS environment variable which can be used for this purpose.
REDIRECT_STATUS is empty (or not set) on the initial request. It is set to 200 on the first (successful) internal rewrite. Or some other HTTP status code in the case of an error (404 etc.).
So, instead of checking that REDIRECT_LOOP is not 1, we can simply check that REDIRECT_STATUS is empty to ensure we are testing the initial request and not the rewritten request. For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^myscript\.php$ / [R,L]
(Note that it is just REDIRECT_STATUS, there is no STATUS variable at the start of the request.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !myscript\.php
RewriteRule (.*) /test/myscript.php?p=$1 [L,E=LOOP:1]
Aside: The RewriteCond directive that checks against the REQUEST_URI doesn't really do anything here. If the first condition is true (ie. it's not a file), then this condition must also be true. However, it could be optimised by including this condition first. This would then avoid the file check on every request (including the rewritten request). For example:
RewriteCond %{REQUEST_URI} !^/test/myscript\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /test/myscript.php?p=$1 [L]
Or, you could include a pre-check (an exception) before this rule instead that halts processing when myscript.php is requested:
RewriteRule ^test/myscript\.php$ - [L]
However, if you do this, then the above canonical redirects must appear before these rules, otherwise they will never be processed. (Putting the canonical redirects first is generally preferable anyway.)