त्रुटि पर स्क्रिप्ट लाइन नंबर?


105

यदि मैं कमांड लाइन (R --slave script.R) से लंबी आर स्क्रिप्ट चला रहा हूं, तो मैं इसे त्रुटियों के लिए लाइन नंबर कैसे दे सकता हूं?

यदि संभव हो तो मैं स्क्रिप्ट में डिबग कमांड जोड़ना नहीं चाहता हूं - मैं चाहता हूं कि आर अधिकांश अन्य स्क्रिप्टिंग भाषाओं की तरह व्यवहार करे ...


31
कोई सुधार? चार 4 साल बाद, लगता है कि समस्या अभी भी बनी हुई है, आर। के सभी मुख्यधारा को अपनाने के बावजूद
गुई एम्ब्रोस

मेरे पास बहुत लंबी आर स्क्रिप्ट है जिसमें बहुत सारे छोटे आउटपुट हैं, मैं चाहता हूं कि (अंडरस्कोर) अंडरस्कोर (अंडरस्कोर) लाइन / फाइल (अंडरस्कोर) (अंडरस्कोर) (लाइन नंबर और स्क्रिप्टनेम) सी में उस तरह से हो, हार्डकोडिंग लाइन-नंबरों के बजाय। स्रोत में।
मॉस

मैं नहीं जानता कि क्या आर आंतरिक रूप से 'लाइन नंबर' की धारणा है। हालाँकि, इसमें पूर्ण कार्यों की धारणा है, अर्थात शीर्ष स्तर के कार्य। उदाहरण के लिए, आसानी से एक टास्क हैंडलर को परिभाषित किया जा सकता है ताकि यह बताया जा सके कि कौन-सा टॉप-लेवल कार्य विफल हो गया है। बेशक, बड़ी चेन या बड़े सशर्त बयान वाले लोगों के लिए यह कोई बड़ी सुविधा नहीं है।
रसेलपिएर्स

जवाबों:


45

यह आपको लाइन नंबर नहीं देगा, लेकिन यह आपको बताएगा कि कॉल स्टैक में विफलता कहां होती है जो बहुत सहायक होती है:

traceback()

[संपादित करें:] कमांड लाइन से एक स्क्रिप्ट चलाते समय आपको एक या दो कॉल को छोड़ना होगा, इंटरेक्टिव और गैर-इंटरैक्टिव आर सत्रों के लिए ट्रेसबैक देखें ()

मैं सामान्य डिबगिंग संदिग्धों के बिना ऐसा करने के अन्य तरीके से अवगत नहीं हूं:

  1. डिबग ()
  2. ब्राउज़र ()
  3. विकल्प (त्रुटि = पुनर्प्राप्त) [इसे वापस करने के लिए विकल्प (त्रुटि = NULL) के बाद]

आप इस संबंधित पोस्ट को देखना चाह सकते हैं।

[संपादित करें:] क्षमा करें ... बस देखा कि आप इसे कमांड लाइन से चला रहे हैं। उस मामले में मैं विकल्प (त्रुटि) कार्यक्षमता के साथ काम करने का सुझाव दूंगा। यहाँ एक सरल उदाहरण दिया गया है:

options(error = quote({dump.frames(to.file=TRUE); q()}))

आप एक स्क्रिप्ट के रूप में बना सकते हैं जैसा कि आप एक त्रुटि स्थिति पर चाहते हैं, इसलिए आपको बस यह तय करना चाहिए कि आपको डीबगिंग के लिए कौन सी जानकारी चाहिए।

अन्यथा, यदि ऐसे विशिष्ट क्षेत्र हैं जिनके बारे में आप चिंतित हैं (उदाहरण के लिए किसी डेटाबेस से कनेक्ट करना), तो उन्हें tryCatch () फ़ंक्शन में लपेटें।


पहले [संपादित करें]] ब्लॉक से जुड़ा समाधान मेरे लिए काम करता है। सबसे अच्छा तरीका @dshepherd की टिप्पणी लगता है, यानी, options(error=function() { traceback(2); if(!interactive()) quit("no", status = 1, runLast = FALSE) })(स्वीकृत उत्तर की टिप्पणी देखें)। मुझे लगता है कि इसका अर्थ केवल दूसरे धागे का लिंक प्रदान करने के बजाय इसे यहाँ उत्तर में जोड़ना होगा।
cryo111

1
एक नया विकल्प है कि आप ट्रेसबैक github.com/aryoda/tryCatchLog
लुगुनी

13

करना options(error=traceback), त्रुटि के लिए अग्रणी लाइनों की सामग्री के बारे में थोड़ी और जानकारी प्रदान करता है। यदि कोई त्रुटि है, तो यह ट्रेसबैक प्रकट होने का कारण बनता है, और कुछ त्रुटियों के लिए इसके द्वारा उपसर्गित लाइन नंबर है #। लेकिन यह हिट या मिस है, कई त्रुटियों को लाइन नंबर नहीं मिलेगा।


2
मेरे लिए काफी काम नहीं करता है। मुझे केवल एक फ़ाइल मिली है, और यह लाइन नंबर नहीं दिखाता है, बस No traceback availableत्रुटि के बाद कहता है ।
निशान लता

11

इसके लिए समर्थन आर 2.10 और बाद में आगामी होगा। डंकन मर्डोक सिर्फ 10 सितं, 2009 के बारे में पर आर-devel पर पोस्ट किए गए findLineNum और setBreapoint :

मैंने डीबगिंग में मदद करने के लिए R-devel में कुछ फ़ंक्शन जोड़े हैं। findLineNum()यह पता चलता है कि कौन सी लाइन किस फ़ंक्शन के स्रोत कोड की एक विशेष लाइन से मेल खाती है; setBreakpoint()का उत्पादन लेता है findLineNum, और trace()वहां एक ब्रेकपॉइंट सेट करने के लिए कॉल करता है।

ये कोड में स्रोत संदर्भ डीबग जानकारी होने पर निर्भर करते हैं। यह कोड पढ़ने के लिए डिफ़ॉल्ट है source(), लेकिन पैकेज के लिए नहीं। पैकेज कोड में स्रोत संदर्भ प्राप्त करने के लिए, पर्यावरण चर सेट करें R_KEEP_PKG_SOURCE=yes, या आर के भीतर सेट करें options(keep.source.pkgs=TRUE), फिर स्रोत कोड से पैकेज स्थापित करें। ?findLineNumवैश्विक पर्यावरण की खोज को सीमित करने के बजाय, पैकेजों के भीतर खोजने के लिए इसे कैसे बताया जाए, इसके विवरण के लिए पढ़ें ।

उदाहरण के लिए,

x <- " f <- function(a, b) {
             if (a > b)  {
                 a
             } else {
                 b
             }
         }"


eval(parse(text=x))  # Normally you'd use source() to read a file...

findLineNum("<text>#3")   # <text> is a dummy filename used by
parse(text=)

यह छपेगा

 f step 2,3,2 in <environment: R_GlobalEnv>

और आप उपयोग कर सकते हैं

setBreakpoint("<text>#3")

वहाँ एक ब्रेकपॉइंट सेट करने के लिए।

कोड में अभी भी कुछ सीमाएँ (और शायद बग) हैं; मैं थॉस फिक्स कर रहा हूं


धन्यवाद। बस r-devel मेलिंग सूची के लिए भी साइन अप किया गया। मैं इस धारणा पर आर-हेल्प से बच रहा हूं कि यह मेरे इनबॉक्स को रोक देगा (आर-सिग-फाइनेंस पहले से ही ऐसा करता है)।
शेन

1
वास्तव में यह समझ में नहीं आता है कि यह कमांड लाइन से आर स्क्रिप्ट में घूमने के बिना कैसे काम करता है
हरमन टूथ्रोट

1
@ हिरसे: यह आपका लगभग दस पुराना उत्तर है। पृथ्वी पर आपने मुझे उद्धृत करने के बहाने इसका सुधार क्यों किया? मैं नहीं था, और आपका परिवर्तन मेरे इरादे को नहीं दर्शाता है।
डिर्क एडल्डबुलेटेल

"डंकन मर्डोक ने अभी पोस्ट किया है:" एक बोली बहुत पसंद है, लेकिन अगर यह सही नहीं है, तो कृपया संपादन को वापस कर दें। मैं इसे अपने लिए अधिक पठनीय बनाना चाहता था और जब तक मैं ऐसा नहीं करता था, तारीख की जाँच नहीं करता था। यदि पूरा उत्तर बहुत पुराना है, तो आप इसे भविष्य के पाठकों के लिए भ्रम को दूर करने के लिए भी हटा सकते हैं।
h

क्या आप इसे वापस कर सकते हैं? धन्यवाद।
डिर्क एडल्डबुलेटेल

6

आप इसे सेटिंग करके करें

options(show.error.locations = TRUE)

मुझे आश्चर्य है कि यह सेटिंग R में डिफ़ॉल्ट क्यों नहीं है? यह होना चाहिए, जैसा कि हर दूसरी भाषा में होता है।


1
इस विकल्प के बारे में पृष्ठभूमि की जानकारी के लिए stat.ethz.ch/R-manual/R-devel/library/base/html/options.html
R Yoda

1
यह काम करता था, लेकिन यह अक्षम था क्योंकि यह विश्वसनीय नहीं है। मुझे लगता है कि यह आपको RStudio का उपयोग करने के लिए मजबूर करने का एक प्रयास है जो अंततः गैर-मुक्त होगा।
एरिक लेसचिंस्की

6
मुझे शक है। R कोर और RStudio बहुत अलग संगठन हैं, और विशेष रूप से R कोर खुले-खट्टे हैं।
बेन बोल्कर

CentOS 6.9 पर काम किया, आर 3.4.2
irritable_phd_syndrom

शायद यह ध्यान देने योग्य है, आपको किसी भी कोड को सोर्स करने से पहले विकल्पों को सामने सेट करना चाहिए।
जोपंते

3

त्रुटि के बारे में जानकारी बनाए रखने और विफलता के बाद इस जानकारी की जांच करने के लिए एक अनुकूलित वर्कफ़्लो के साथ, गैर-विपत्तिपूर्ण त्रुटियों से निपटने के लिए वैश्विक आर विकल्प को निर्दिष्ट करना। मैं वर्तमान में R संस्करण 3.4.1 चला रहा हूं। नीचे, मैंने उन वर्कफ़्लो का विवरण शामिल किया है जो मेरे लिए काम करते थे, साथ ही कुछ कोड जो मैंने आर में वैश्विक त्रुटि हैंडलिंग विकल्प सेट करने के लिए उपयोग किया था।

जैसा कि मैंने इसे कॉन्फ़िगर किया है, त्रुटि हैंडलिंग भी त्रुटि के समय काम करने वाली मेमोरी में सभी वस्तुओं से युक्त एक RData फ़ाइल बनाता है। इस डंप को R उपयोग में वापस पढ़ा जा सकता है load()और फिर विभिन्न वातावरण के रूप में वे त्रुटि के समय मौजूद थे, का उपयोग करके अंतःक्रियात्मक रूप से निरीक्षण किया जा सकता है debugger(errorDump)

मैं ध्यान दूंगा कि मैं traceback()स्टैक के भीतर किसी भी कस्टम फ़ंक्शन से आउटपुट में लाइन नंबर प्राप्त करने में सक्षम था , लेकिन केवल तभी जब मैंने अपनी स्क्रिप्ट में उपयोग किए गए किसी भी कस्टम फ़ंक्शन के लिए keep.source=TRUEकॉल source()करते समय विकल्प का उपयोग किया था। इस विकल्प के बिना, नीचे दिए गए traceback()त्रुटि लॉग के पूर्ण आउटपुट के रूप में वैश्विक त्रुटि से निपटने के विकल्प को सेट करना error.log, लेकिन लाइन नंबर उपलब्ध नहीं थे।

यहां मैंने अपने वर्कफ़्लो में सामान्य कदम उठाए हैं और मैं एक गैर-इंटरैक्टिव आर विफलता के बाद मेमोरी डंप और त्रुटि लॉग तक कैसे पहुंच सकता हूं।

  1. मैंने मुख्य स्क्रिप्ट को कमांड लाइन से कॉल कर रहा था, उसके शीर्ष पर निम्नलिखित रखा। यह R सत्र के लिए वैश्विक त्रुटि हैंडलिंग विकल्प सेट करता है। मेरी मुख्य स्क्रिप्ट को बुलाया गया था myMainScript.R। कोड की विभिन्न पंक्तियों में उनके द्वारा की गई टिप्पणियों का वर्णन है कि वे क्या करते हैं। मूल रूप से, इस विकल्प के साथ, जब आर एक त्रुटि का सामना करता है जो ट्रिगर करता है stop(), तो यह निर्देशिका में सभी सक्रिय वातावरणों में कार्यशील मेमोरी का एक आरडीएटा (* .rda) डंप फ़ाइल बनाएगा ~/myUsername/directoryForDumpऔर error.logकुछ उपयोगी जानकारी के साथ नाम त्रुटि लॉग भी लिखेगा । एक ही निर्देशिका। आप त्रुटि पर अन्य हैंडलिंग जोड़ने के लिए इस स्निपेट को संशोधित कर सकते हैं (जैसे, डंप फ़ाइल में एक टाइमस्टैम्प जोड़ें और त्रुटि लॉग फ़ाइलनाम, आदि)।

    options(error = quote({
      setwd('~/myUsername/directoryForDump'); # Set working directory where you want the dump to go, since dump.frames() doesn't seem to accept absolute file paths.
      dump.frames("errorDump", to.file=TRUE, include.GlobalEnv=TRUE); # First dump to file; this dump is not accessible by the R session.
      sink(file="error.log"); # Specify sink file to redirect all output.
      dump.frames(); # Dump again to be able to retrieve error message and write to error log; this dump is accessible by the R session since not dumped to file.
      cat(attr(last.dump,"error.message")); # Print error message to file, along with simplified stack trace.
      cat('\nTraceback:');
      cat('\n');
      traceback(2); # Print full traceback of function calls with all parameters. The 2 passed to traceback omits the outermost two function calls.
      sink();
      q()}))
  2. सुनिश्चित करें कि मुख्य स्क्रिप्ट और किसी भी बाद के फ़ंक्शन कॉल से, कभी भी किसी फ़ंक्शन को खट्टा keep.source=TRUEकिया जाता है , विकल्प का उपयोग किया जाता है। यही है, एक समारोह के स्रोत के लिए, आप उपयोग करेंगे source('~/path/to/myFunction.R', keep.source=TRUE)traceback()आउटपुट के लिए लाइन नंबरों को शामिल करना आवश्यक है । ऐसा लगता है कि आप इस विकल्प को विश्व स्तर पर उपयोग करने में सक्षम हो सकते हैं options( keep.source=TRUE ), लेकिन मैंने यह देखने के लिए यह परीक्षण नहीं किया है कि यह काम करता है या नहीं। यदि आपको पंक्ति संख्याओं की आवश्यकता नहीं है, तो आप इस विकल्प को छोड़ सकते हैं।

  3. टर्मिनल (आर के बाहर) से, मुख्य स्क्रिप्ट को बैच मोड में उपयोग करके कॉल करें Rscript myMainScript.R। यह एक नया गैर-इंटरैक्टिव आर सत्र शुरू करता है और स्क्रिप्ट चलाता है myMainScript.R। चरण 1 में दिए गए कोड स्निपेट को myMainScript.Rसेट किया गया है जो गैर-इंटरैक्टिव आर सत्र के लिए त्रुटि हैंडलिंग विकल्प सेट करता है।
  4. के निष्पादन के भीतर कहीं त्रुटि का सामना करना myMainScript.R। यह मुख्य लिपि में ही हो सकता है, या कई कार्यों को गहनता से निहित कर सकता है। जब त्रुटि का सामना करना पड़ता है, तो चरण 1 में निर्दिष्ट अनुसार हैंडलिंग का प्रदर्शन किया जाएगा, और आर सत्र समाप्त हो जाएगा।
  5. RDD डंप फ़ाइल नाम errorDump.rdaऔर त्रुटि लॉग नाम वैश्विक त्रुटि हैंडलिंग विकल्प सेटिंग error.logद्वारा निर्दिष्ट निर्देशिका में बनाई गई हैं '~/myUsername/directoryForDump'
  6. अपने अवकाश पर, error.logत्रुटि के बारे में जानकारी की समीक्षा करने के लिए निरीक्षण करें, जिसमें त्रुटि संदेश स्वयं और पूर्ण स्टैक ट्रेस त्रुटि के लिए अग्रणी है। यहां उस लॉग का एक उदाहरण है जो त्रुटि पर उत्पन्न होता है; #वर्ण के बाद संख्याओं पर ध्यान दें कि कॉल स्टैक में विभिन्न बिंदुओं पर त्रुटि की रेखा संख्याएं हैं:

    Error in callNonExistFunc() : could not find function "callNonExistFunc"
    Calls: test_multi_commodity_flow_cmd -> getExtendedConfigDF -> extendConfigDF
    
    Traceback:
    3: extendConfigDF(info_df, data_dir = user_dir, dlevel = dlevel) at test_multi_commodity_flow.R#304
    2: getExtendedConfigDF(config_file_path, out_dir, dlevel) at test_multi_commodity_flow.R#352
    1: test_multi_commodity_flow_cmd(config_file_path = config_file_path, 
    spot_file_path = spot_file_path, forward_file_path = forward_file_path, 
    data_dir = "../", user_dir = "Output", sim_type = "spot", 
    sim_scheme = "shape", sim_gran = "hourly", sim_adjust = "raw", 
    nsim = 5, start_date = "2017-07-01", end_date = "2017-12-31", 
    compute_averages = opt$compute_averages, compute_shapes = opt$compute_shapes, 
    overwrite = opt$overwrite, nmonths = opt$nmonths, forward_regime = opt$fregime, 
    ltfv_ratio = opt$ltfv_ratio, method = opt$method, dlevel = 0)
  7. अपने अवकाश पर, आप errorDump.rdaएक इंटरैक्टिव R सत्र का उपयोग करके लोड कर सकते हैं load('~/path/to/errorDump.rda')। एक बार लोड होने पर, debugger(errorDump)किसी भी सक्रिय वातावरण में मेमोरी में सभी आर ऑब्जेक्ट्स ब्राउज़ करने के लिए कॉल करें। debugger()अधिक जानकारी के लिए R मदद देखें ।

कुछ प्रकार के उत्पादन वातावरण में R को चलाने पर यह वर्कफ़्लो काफी सहायक होता है, जहाँ आपके पास कमांड लाइन पर गैर-संवादात्मक R सत्र आरंभ हो रहे हैं और आप अनपेक्षित त्रुटियों के बारे में जानकारी बरकरार रखना चाहते हैं। किसी फ़ाइल में मेमोरी को डंप करने की क्षमता, आप कॉल स्टैक में त्रुटि की लाइन संख्या होने के साथ-साथ त्रुटि के समय काम करने वाली मेमोरी का निरीक्षण करने के लिए उपयोग कर सकते हैं, जो त्रुटि का कारण पोस्टमार्टम डिबगिंग की सुविधा प्रदान करता है।


0

पहले, options(show.error.locations = TRUE)और फिर traceback()। # के बाद त्रुटि लाइन नंबर प्रदर्शित किया जाएगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.