Код выхода при вызове сценария R из bash

У меня есть сценарий R, который я вызываю из интерактивной оболочки bash (MacOS Catalina). Это один из серии сценариев, которые я вызываю из интерактивной оболочки, поэтому мне нужно знать, не удалось ли выполнить исходный сценарий. Кажется, что независимо от того, как сценарий терпит неудачу (assert_that, stop, stopfinot, quit), R всегда возвращает статус выхода 0. Как я могу вернуть ненулевой статус существования из неудачного сценария R?

Вот пример сценария R (fail.r).

#!/usr/bin/env Rscript

#library(assertthat)

message("Starting script")

#assert_that(FALSE)

#stop('Fail')

#stopifnot(FALSE)

q(save="no", status=10, runLast=FALSE)

message("Should not reach here")

И вот как я могу назвать это из командной строки bash

src/poc/fail.r

echo $?

Независимо от метода, который я использую для выхода из сценария R $? всегда возвращает 0.

Пара других сообщений посвящена этой проблеме, но, похоже, не относится к моей ситуации (Как заставить Rscript возвращать код состояния в неинтерактивном режиме bash) и (Сделайте выход R с ненулевым кодом статуса)


person Ben Carlson    schedule 14.09.2020    source источник


Ответы (1)


Я могу получить статус из Rscript обратно в вызывающую оболочку (R версии 4.0.2, bash версии 3.2.57 или zsh версии 5.8, работающей на MacBook Pro, macOS Mohave 10.14.6), используя q(status = N). Чтобы получить ненулевой статус выхода из неудачного сценария R, используйте q(status = 2) или выше, см. _ 3_:

$ Rscript -e 'q(status = 0);'
$ echo $?
0

$ Rscript -e 'q(status = 2);'
$ echo $?
2

$ Rscript -e 'q(status = 10);'
$ echo $?
10

$ R --version
R version 4.0.2 (2020-06-22) -- "Taking Off Again"
Copyright (C) 2020 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin13.4.0 (64-bit)

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)

$ zsh --version
zsh 5.8 (x86_64-apple-darwin17.7.0)

Используя сценарий, по сути идентичный тому, который вы опубликовали, я получаю ожидаемые результаты (статус от quit успешно передается в оболочку):

Сценарий:

#!/usr/bin/env Rscript

message("Starting script")
## Use status = 0, 2 or 10:
q(save = "no", status = 2, runLast = FALSE)
message("Should not reach here")

Вывод (проверено с показанными выше версиями zsh и bash):

$ ~/test/test1.r
Starting script
$ echo $?       
0
$ ~/test/test1.r
Starting script
$ echo $?       
2
$ ~/test/test1.r
Starting script
$ echo $?       
10

СМОТРИ ТАКЖЕ:

Некоторые значения статуса ошибки используются самим R. Обработчик ошибок по умолчанию для неинтерактивного использования фактически вызывает q (no, 1, FALSE) и возвращает статус ошибки 1. Статус ошибки 2 используется для R "самоубийство", то есть катастрофический сбой, а другие небольшие числа используются конкретными порты для сбоев инициализации. Пользователям рекомендуется выбирать статусы от 10 и более.

Допустимые значения статуса зависят от системы, но обычно допустимы значения 0: 255.

(Из quit документы)

person Timur Shtatland    schedule 14.09.2020
comment
Спасибо @Timur, ваш пример помог мне понять, в чем дело. Rscript запускал .Rprofile, который загружал кучу пакетов и устанавливал некоторые параметры. Что-то там должно было мешать возврату статуса выхода. Когда я сделал Rscript --vanilla, статус выхода был возвращен правильно. Rscript --vanilla -e 'q (status = 2);' эхо $? Это также работало при вызове сценария с использованием shebang: #! / Usr / bin / env Rscript --vanilla - person Ben Carlson; 17.09.2020
comment
@BenCarlson Я рад, что мой ответ оказался полезным! Я рекомендую превратить ваш комментарий в ответ и принять ваш собственный ответ (и, таким образом, отклонить мой ответ в процессе). Ваш ответ поможет будущим пользователям устранять подобные проблемы. Мне не приходило в голову, что .Rprofile и Rscript --vanilla были ключом к ответу. Я, конечно же, сохраню свой ответ, так как он может быть полезен и другим. :) - person Timur Shtatland; 17.09.2020