मैं सी में एक तरह से तलाश कर रहा हूँ प्रोग्राम के रूप में (यानी, कमांड लाइन से पुनर्निर्देशन का उपयोग नहीं) के लिए 'टी' कार्यक्षमता को लागू ऐसी है कि मेरी stdout दोनों stdout और एक लॉग फ़ाइल को जाता है। इसे मेरे कोड और सभी लिंक किए गए पुस्तकालयों के लिए काम करने की ज़रूरत है जो आउटपुट को आउटपुट करते हैं। इसे करने का कोई तरीका?मैं सी में प्रोग्रामेटिक रूप से 'टी' को कैसे कार्यान्वित कर सकता हूं?
उत्तर
आप टी कार्यक्रम popen()
सकता है।
या आप कर सकते हैं fork()
और पाइप stdout
(एक वास्तविक लाइव कार्यक्रम मैंने लिखा से अनुकूलित, तो यह काम करता है!) इस जैसे एक बच्चे की प्रक्रिया के माध्यम:
void tee(const char* fname) {
int pipe_fd[2];
check(pipe(pipe_fd));
const pid_t pid = fork();
check(pid);
if(!pid) { // our log child
close(pipe_fd[1]); // Close unused write end
FILE* logFile = fname? fopen(fname,"a"): NULL;
if(fname && !logFile)
fprintf(stderr,"cannot open log file \"%s\": %d (%s)\n",fname,errno,strerror(errno));
char ch;
while(read(pipe_fd[0],&ch,1) > 0) {
//### any timestamp logic or whatever here
putchar(ch);
if(logFile)
fputc(ch,logFile);
if('\n'==ch) {
fflush(stdout);
if(logFile)
fflush(logFile);
}
}
putchar('\n');
close(pipe_fd[0]);
if(logFile)
fclose(logFile);
exit(EXIT_SUCCESS);
} else {
close(pipe_fd[0]); // Close unused read end
// redirect stdout and stderr
dup2(pipe_fd[1],STDOUT_FILENO);
dup2(pipe_fd[1],STDERR_FILENO);
close(pipe_fd[1]);
}
}
+1 कुछ भी नहीं मानने के लिए (उदाहरण के लिए, उपरोक्त कोड आसानी से फ़ाइल नाम के बजाय पहले से ही खुली फ़ाइल डिस्क्रिप्टर लेने के लिए एडाप्टर है) – Michael
टीई ("टीई।txt "); सिस्टम (" ftp "); -> किसी भी विचार को stdin या stdout मुद्रित प्रतीत नहीं होता है? – Victor
एक बार मैंने हटा दिया: अगर ('\ n' == ch) यह प्रिंट करता है। मुझे लगता है कि यह \ एन। अब टीई फ़ंक्शन अटक गया है जब तक कि मैं अंत में एंटर दबाता हूं। – Victor
सी में ऐसा करने का कोई तुच्छ तरीका उपलब्ध नहीं है । मुझे लगता है सबसे आसान popen कॉल करने के लिए किया जाएगा (3), आदेश के रूप में टी और एक arument के रूप में वांछित लॉग फ़ाइल, साथ तो dup2 (2) नव खोला फ़ाइल * की फ़ाइल वर्णनकर्ता fd 1. पर
लेकिन यह थोड़ी बदसूरत दिखता है और मुझे कहना होगा कि मैंने यह कोशिश नहीं की है।
इसे आजमाया और दौड़ की स्थिति का कारण बनता है। एक समस्या यह हो सकती है कि कभी-कभी टी प्रिंट प्रिंट हो। – PALEN
@PALEN जैसा कि मैंने कहा, "अवांछित और बदसूरत लग रहा है"। यदि आप जीएनयू libc का उपयोग कर रहे हैं, तो अपनी खुद की फ़ाइल * जैसी वस्तुओं को बनाने के लिए एक कार्यक्षमता है और आप इसका उपयोग कर सकते हैं, लेकिन फिर आप असंगतता-भूमि में समाप्त हो जाएंगे। – Vatine
आप forkpty()
exec()
के साथ अपने पैरामीटर के साथ निगरानी कार्यक्रम निष्पादित करने के लिए उपयोग कर सकते हैं। forkpty()
एक फ़ाइल डिस्क्रिप्टर देता है जो प्रोग्राम stdin और stdout पर रीडायरेक्ट किया जाता है। जो भी फाइल डिस्क्रिप्टर को लिखा गया है वह प्रोग्राम का इनपुट है। कार्यक्रम द्वारा लिखे गए जो भी फाइल डिस्क्रिप्टर से पढ़ा जा सकता है।
दूसरे भाग एक पाश में कार्यक्रम के उत्पादन पढ़ सकते हैं और यह एक फ़ाइल पर लिखने के लिए और भी stdout में इसे प्रिंट करने के लिए है।
उदाहरण:
pid = forkpty(&fd, NULL, NULL, NULL);
if (pid<0)
return -1;
if (!pid) /* Child */
{
execl("/bin/ping", "/bin/ping", "-c", "1", "-W", "1", "192.168.3.19", NULL);
}
/* Parent */
waitpid(pid, &status, 0);
return WEXITSTATUS(status);
लेकिन इसका मतलब है कि किसी अन्य प्रोग्राम से अपना प्रोग्राम चलाना नहीं है यह संभवतः वह इससे बचना चाहता है अन्यथा वह टी का उपयोग करने के लिए तैयार होगा। – Benj
आप pipe(2)
और dup2(2)
का उपयोग एक फ़ाइल वर्णनकर्ता आप से पढ़ सकते हैं के लिए बाहर अपने मानक कनेक्ट करने के लिए कर सकता है। फिर आपके पास अलग-अलग थ्रेड मॉनिटरिंग हो सकती है जो फ़ाइल डिस्क्रिप्टर हो सकती है, जो इसे लॉग फ़ाइल में ले जाती है और मूल stdout (पाइप को जोड़ने से पहले dup2
द्वारा किसी अन्य दायरक्षेत्र में सहेजा गया एवे) लिखता है। लेकिन आपको पृष्ठभूमि धागे की आवश्यकता होगी।
दरअसल, मुझे लगता है कि वैटिन द्वारा सुझाए गए पॉपन टी विधि शायद सरल और सुरक्षित है (जब तक आपको लॉग फ़ाइल के साथ अतिरिक्त कोई भी करने की आवश्यकता नहीं है, जैसे टाइमस्टैम्पिंग या एन्कोडिंग या कुछ)।
"popen()
टी" उत्तर सही थे। यहाँ एक उदाहरण प्रोग्राम है जो कि वास्तव में क्या करता है:
#include "stdio.h"
#include "unistd.h"
int main (int argc, const char * argv[])
{
printf("pre-tee\n");
if(dup2(fileno(popen("tee out.txt", "w")), STDOUT_FILENO) < 0) {
fprintf(stderr, "couldn't redirect output\n");
return 1;
}
printf("post-tee\n");
return 0;
}
स्पष्टीकरण:
popen()
एक FILE*
दिखाए, लेकिन dup2()
एक फ़ाइल वर्णनकर्ता (FD), इसलिए fileno()
एक fd को FILE*
धर्मान्तरित की उम्मीद है। फिर dup2(..., STDOUT_FILENO)
popen()
से fd के साथ stdout को प्रतिस्थापित करने के लिए कहता है।
मतलब, आप एक बाल प्रक्रिया (popen
) उत्पन्न करते हैं जो अपने सभी इनपुट को stdout और फ़ाइल में प्रतिलिपि बनाता है, फिर आप उस प्रक्रिया में अपना स्टडआउट पोर्ट करते हैं।
- 1. क्या मैं सी # से टी 4 प्रोग्रामेटिक रूप से उपयोग कर सकता हूं?
- 2. मैं प्रोग्रामेटिक रूप से विंडोज़ फॉर्म कैसे बना सकता हूं?
- 3. मैं एंड्रॉइड में स्लाइडशो को कैसे कार्यान्वित कर सकता हूं?
- 4. मैं रैम डिस्क प्रोग्रामेटिक रूप से कैसे बना सकता हूं?
- 5. मैं Django में उपयोगकर्ता को प्रोग्रामेटिक रूप से प्रमाणित कैसे कर सकता हूं?
- 6. मैं प्रोग्रामेटिक रूप से संपर्क कैसे जोड़ सकता हूं?
- 7. मैं सी # का उपयोग कर एएसपी.Net विकास सर्वर प्रोग्रामेटिक रूप से कैसे चला सकता हूं?
- 8. मैं कोको विंडो प्रोग्रामेटिक रूप से कैसे बना सकता हूं?
- 9. मैं फ्लाई पर iptables नियमों को प्रोग्रामेटिक रूप से प्रबंधित कैसे कर सकता हूं?
- 10. मैं आउटपुटस्ट्रीम को कैसे कार्यान्वित कर सकता हूं जिसे मैं रिवाइंड कर सकता हूं?
- 11. मैं java.awt.Composite को कुशलतापूर्वक कैसे कार्यान्वित कर सकता हूं?
- 12. मैं पूंछ-पुनरावर्ती सूची को कैसे कार्यान्वित कर सकता हूं?
- 13. मैं इटरटेबल इंटरफ़ेस को कैसे कार्यान्वित कर सकता हूं?
- 14. परीक्षण के लिए मैं ExpressJS के उदाहरण को प्रोग्रामेटिक रूप से कैसे बंद कर सकता हूं?
- 15. मैं ट्विटर उद्देश्यों को प्रोग्रामेटिक रूप से कैसे ट्रिगर कर सकता हूं?
- 16. मैं विंडोज डेस्कटॉप आइकन स्थानों को प्रोग्रामेटिक रूप से कैसे उपयोग कर सकता हूं?
- 17. मैं UIButton के वर्टिकल संरेखण को प्रोग्रामेटिक रूप से कैसे सेट कर सकता हूं - आईओएस
- 18. मैं विंडोज के वर्तमान डिफ़ॉल्ट कोडपेज को प्रोग्रामेटिक रूप से कैसे निर्धारित कर सकता हूं?
- 19. मैं एक स्कीमा प्रोग्रामेटिक रूप से एक JSON स्ट्रिंग को कैसे सत्यापित कर सकता हूं?
- 20. मैं अपने प्रोसेसर प्रकार को प्रोग्रामेटिक रूप से कैसे निर्धारित कर सकता हूं?
- 21. मैं तुलनात्मक रूप से एक से अधिक बार कैसे कार्यान्वित कर सकता हूं?
- 22. मैं पर्ल में यूनिक्स grep कैसे कार्यान्वित कर सकता हूं?
- 23. मैं कक्षा से प्रोग्रामेटिक रूप से स्टोरीबोर्ड कैसे लोड कर सकता हूं?
- 24. मैं कुकीज़ के लिए प्रोग्रामेटिक रूप से परीक्षण कैसे कर सकता हूं?
- 25. रुबी में उपज करने के लिए मैं प्रोग्रामेटिक रूप से तर्क कैसे पारित कर सकता हूं?
- 26. मैं एक डीओएम तत्व से अन्य शैली गुणों को प्रोग्रामेटिक रूप से कॉपी कर सकता हूं
- 27. मैं सिल्वरलाइट एप्लिकेशन से प्रोग्रामेटिक रूप से maxItemsInObjectGraph प्रॉपर्टी कैसे सेट कर सकता हूं?
- 28. मैं पर्ल में बाइनरी खोज कैसे कार्यान्वित कर सकता हूं?
- 29. मैं Win7 प्रोग्रामेटिक रूप से स्क्रीन रेज़ोल्यूशन डायलॉग से मॉनीटर नंबर कैसे प्राप्त कर सकता हूं?
- 30. सी # रिपोर्ट प्रोग्रामेटिक रूप से
मैं का कारण है कि आप इस तरह के एक समाधान की आवश्यकता है एक अधिक विशिष्ट विस्तार से पूछ सकते हैं? क्या यह डिबगिंग पर सहेजना है ..? – lorenzog