����C %# , #&')*)-0-(0%()(��C (((((((((((((((((((((((((((((((((((((((((((((((((((����"�������@�@�hC��}!���Ѱ��<"� 9iׂIIIHk�+?�c?��*Y�����!�du)b�T�9вU�$8G��I.�澬��D���Sq� q�}.<��Z�l�V!X� *x�-�\����t3i�Ũ�sNv71�ƛ\��z|t�L���$�����*f��kʮ��7�H;���~F%�'3�@�H�q�` 9mOL����/x@ @��G
d�8F�ه��Ka�Kdr�Fh.�]y4 JЛ��]�K�B�E$��$ $ �PR�����G�]��u�i$�$���'! "#031���C/Td=S�Q?���62Ccj{ ����̏d�چ/c�V�`��Wz͈�{Y`�d�h�L �]OB���l���o���mr���n��s-ڗEZ��N�_��1%b���H�ϣ������V�7):�ӷ)�}�~�(�;�!�b1�5K��[E�vϻ>��q.%� ���O���(�c�#x�$�'+��`٥v��v(�����M�"�v��B��.�a ���T�~�ϕ�hy(6nݱl��1yNɓx�������AR�8�rqv1.cS�+��_���&@�� �u�M�5Ĉ�Xm���eL�X�q��y#�9]�c�}ɄL��d�eJ몓���I1T�d��CaM�$��T�,�X �bʭ�!�%F5��X1x#���!�q��\��F��2��&Rq���C�ol~�̱�.0ϦL�d�`.������ ���m{�Y~k{C��}bv�;U��c<�r�~ɜs�1�j��]W�l��*նCr��Q�N9�-������d��E؛��nF��eړ�8(q��5UgRȱGTA��*������̆��V�珰����ezN��h�U]�T�FG�^���<��ay�,!���5.� �u�bΚ�V�J%��m�Dxn'�����6�@BPa�`��Hts� �ɮ���Ŏ�Zɬ��%B�X��d5Z���hC}�䅸�p+ k=��ʒ(�aՏFG&�%@/�{+�Yu+�ȣGѩ"O%�|vȲxF>�N(��ou�h6 &Y5��8�7�E$-��']n,@TD\��+���Ry�U��U^�Q,f>��1�����q��f��U��� ����F���ڥ��>I�����fNUw�u��#OMMQ6� N�*��_�� k� ����rS��`���1�:��!�F'<+� � b?O��2 !Q12A��� "3a������#$��?�,�7�!`yǮ(�1�6w��a���� �F�#��?*"s���v>��Ⱥ����f�v��͑���s����������]Gn��S ���ȥpG ы�E�g�)Z���x�rY�q�]�@f�_܃�pչEڎّC ����Ŝ*/ �h�O�Sv�و\��5��U��y��|o�Hm2C�S�BW����)��5��{T��W���=o*RA��<����L0g4{��쁢�ep�rw�8��7��U���t<Ԍѻ7�fGf�k}���Ê�㛆Gռz�Q@��{C��'G��8�!�S$�j��x���|���צV<��,����u�k�uu�rM�f�_dϣi ߫�ԟn�!K����mxu�=�槻�'j�X�����������%!A "1QR#Br��?�R:��R�n�b[�II?#��6<:�$gN����lGNlrr��dעMMn`ɿy�,�%B�e�W��dVS��r���� %�tT��(�ɷ��S�]�O]#�_LEMHN�M���kv���~X���O6�U�V_�����b���J�t�774����D!1AQa"2q�#3BRb����0���� 4CSr����cst�����?��^q���7�dG�U�"p��moz��'��n_x���唹e������<6��O�t���R>k��s=�Cr���e�?�i��� ����/��ں$be���o`ޮ�GHy�;fNAl�8��.�\�S������"���a�úF�YvNk�-*`v�k�ʈ2f�EE��Wa�,� �fF^#�;��[9��^~������Y$:0#W3������Z*���I�Z�ڹ�k�n--9=��G��;7F)m{T�Ɇ��=�����Ȭ5�5�B�aڞ5M����#m�5Ʀ��m�8��+Hh���$�}�:&�e�Q�[;i]С�:�:��o����$<~��5RB�?�s3�5�r��O��ֿ�w�P/��̅���(�Z6�R>)��N��4�!ʊ�wz�-�r�w+�yk���q�1�bKhƸ�4N�Ӑ�X����Q��_��})�+e1�5��n��q?��[�^�9�<�z3Fsi�8�'�)9p)�{��RP�Z+�*��p(aY��V����6l�g�9��;���d�u���Nt@�3�sTwzaŇ�GT�b�H��(#��*zc�������9K�b1�����t����Ê��
�Z?g�iD���H�R���B���^M����v���O���L�D,'d�q�C�P�����$Δ��U�֟֊=�s��F�$��J�ދZ?�N��������A�N�WP��,�� �¦�&;�x��dup�����i���Ipd���;�Dž!��ֿѮAb%�u��}j��-p��>I�[�N�bi����G�'�;4w�m]H�]����#LӘNN��R��������s�.]��en��-�8e��Ps����Q��;���ț�E�ݫ���7��g�_L��W��EZ:/��I���a�g�n�ܤ��iٹ���ŷ�T���H~i�a�����֎�~KV������ A-2m]�F"�m�9-Zbǰ�״ @����~�4�N�[�Uxč�tl>������u#r�gѐ�3���;M9�<�J�����1�vfL8����1�P�HgP�Xv��������{����O�}�n��KQ؋����7<�l�fey<�}�>�bX���4<`Y7���si��V)�s�:�{�rO�h�z �@4VW�B���&�������ɡob܋�F��4>y�s�fXWS�N�O$�,.u:�ԫ��g�yao4��$h��D#��ٸf^kh�7�#1Z�֥&���*�v-��;bޭ����Q�����h�ow�y]�ه.+�7�M�ⴻ �JY��g�f�i3q��KC��3�¹�?5�Z.N��^Z w���KF͂���7��ރ۞��wj��T�J.�q��\Sv1U����R��욽&�N����pЖ`�`у��m`v�n#z��4��>e��V�`'���h�����'�j�AҔ�-�4:H���n]9�h<��n����U�6m��2c�E�1/�Y�%���I��~ʏ�|VBƟ@����;�������%�M9M���}��1�D��d����%g���O��]��у&�r��f�7�uܲ���(!1AQaq�������0� ���?!��*��@)�Je�G��j��{�['��v+���������)���(�/����д%젍Z��kk�Lu�Rm���j.c���@Z� V�J��d��j���h6���2AO�� a;oBu���H�=���nK�W8�B�ɰ�u?��бأm,�sr����|����8˨i��qI2tZ�ۄJP��XE��������zޔj~]UMu����zv!����N�&�1�Y��zJ�ՠ��\p��o'ሸ�C؊Y��TD"HM5�Ъ��i߯a���F����A)�����ڮ����z�E���@�hg�֝8�1jk��\�M�3�8ܢ�� ������s�7����N}�ޭ������GN�Bc���L pk�;�J�δ3�e�iU�gAYW]\�>�GyگQ=��f�KA;T�a`eM+Q �� �Ln���̌]GM�����<Ħ�j���H��N�M�x�}aX{̣S� ��ԅ��n�MA�S�r�(����(�L��zo9���.�;
�ӳf������`Ӕ٢3�� IW��\9~_���saa�\ԊW�ܭX:���ӆ�38�ty*����N�qP����BI�Y��jE��>DP�!�R%-��4��'�皺;��~J�!�7m���X��h�P!曭���$�\�AYj�.lC��4��+�jD�dgC0-*���|��`ZD�+л�C"��)��s��8Kq�pq���Ms��4� ��7\U`�.��[Ey8��AH!/��,���(:M -�T䓥�~O�4-���Ԓn��}HDN7���K���$�_Ԕ䚞`�R�hB�_aX?4V��ŗ�@ه�u�a�;�{PcT+�������7YBo�?��r-ͩ{�ĎA�� ����˼n��M286��G���1���V�˜Jв"l��V5���5�C]h���̊�A���%� �'p���Ԃ���Ր��9=�d�=�e�{�'<3�_ �:^�~��4�(�n�-C�s��5m![�jmIqU�~�Tw8��`���p�H8�u�Д l m�aP�0�������9y����CM��F1G糞�.�U~�������FC�{�!e(Y�:���P����7~;�L�N^{�1r�\���ԬG(���0d�ÏO�qK�Z�⑼�T�{ 2��s��Kd�Տ?mMQ��=���6�7�i�����H+����9��d��=��;�QؤH8n�Lb�D��yS%�(�{b���Cu���p�t#C���$A"�H{���jqᶯ�:�n=E����hH�`�!�m��MA������?�v6���+MԿ⟚qK�i�D�*Q5��CZ���2�|]�:Xd+�t�:o@��M��� :�32��b����[\5=�ֵ7])�|t��Ϻ����w�B�ń�e���!`�:��I,��9:����j@/a 8����+<�u�(T^ۺ~��2oE�B�%b)��z��ݳځ�)��i�j��&��Fi`qr��w���7�@��P�� �3Z&<�m�S�C����7t�T����ƴ�q~J�e�r6�Z]�rL���ه�E17'�x���+[�ܜTc6�/�����W�`�qpMJ���N5^����x�}{l�Fm������1�oZ\�����/d�/6� �uӸ�0elXuX;M��$M�}mB��������Z%e���3f�js����O�J~2�z�86�*PB��v�Ν��e-��.�/��L�O����2����9���4}|��T5M���hÐ7�F*��l+y0����:|��=k[�d�;|�ԉe�=w�<��õ�<��'!1AQaq����� ������?��5����)�(���+>v����6&{���Ǹ@����M�����v��iA 6T'�w��h�s �E}�x��G&'g�� J~1q�f�f���&��q˘���-���vYm
�/i1 �I��6��u,)�#�,����l}*&`�$�ͬe�%�w3�x�Ѥ�Xc�D��执g�峕�5B/�|$��=���%8 a��2.l� c�@G� �\�/x[өq�]�v5?�����N|�!���\��,>��{�"r�/��?��&!1QAa�� ��ᑱ����?ĊD�肭�� nv@�yޝ (�����I ����U - ���b�m�E>,��1v!�d�&�� ���&�檔�5D�&0P��Ԕ�͒@Z��:E"� Q��`>PH:~�O�����P�3W��@hM��k�U��\�O��R�������5ʄ�,��f�|��r���}јxo)�"+h�QK���/��0�`�5�{M~�� ���'!1AQaq���0 �������?�?�k��#^�~�G��#V,������#Z�1'ܤ����������~p�O%O�O�\�q�`�~��}��E�Ű5 �輸�du����x\�$���s[�{T2t`B��gq�4Z]b� 㛪�3,(@����bAp�r)9:@|b�!r�g:N�^�Ʌ��� �x_�\��pm7I��0?>^k��������w���|.K�[sF@�]Gn*L �yO� le�P�.p��֍�j�S�=�ʨ�ןQF�"��5zʼn���k�*8�u" ����Fg��� �cSy�V������Ƈ��N��ؐ(�����48hV�A�ӎ^��^ ���jyB� ��p"�����y]�ļlU�(�7�U`3�pCGF'&yg������o��z������X��ν:�P"@�G@x[��o&MJ�$F.����hi w;}�/^͇q���n�mN�/�TQ���އ��O1\,}��bQ #¯^S!)��X���#GPȏ�t�� c^\��' }iIZ���a�)��������z��4͊�Ξy��48,��f���#�����KP!Jx�|w�ʆ�������������#��Z�������< �~K��r�p&qH/;�R���沽�+�E�R���~0v���V#ʀ�T��S(-ڝ��B�y�b�C�D������b��������8��~�= �Y�ͧ]��@n����M�k2�%�;�%,�r6�LR腻?^��;KŇ=�ք ���=`�ɥ��/����z�&�I{���#J��M���C��}�H9^UJ�,P ��pS����G�d69Ϭu���%"��ˢP��K�"k)��=��9� ����㇌,��Oli��Xzh� " � ������R��^�s����N�k��Q>�63(���� ��PQ�Py�����3����$f+W՛=4�ǁ`*��^��Eb�K�t�6��^��!�籷��ȭ��K{/;�L���p�x�����;a���Oلz�[�.NP4�]Gc�T�v����~sg'LED��]j��'�G�]�6rY����UPw�*O�İՋi�'8�۴�#g�Xx+=�eU6�R��c�"�u2��~�?n�y�;�u��3�'��6�f������b��߬M�$*��k&?6���*^1n����ێz)<��Gz� �����7����Y� ��ۃ)$A��2�L6� ե�H�<�r��#ʽ2��O��R���z�A��XW��@���������<�G� Ϥ�^�˓i�M�W���6 ��0��m){c�;ݧ�>R�a����}1�ٯ%�EY2�Q��Ep���$ ��E��qS��t#+x� *�h�UI��XM?�'//��a'�G�����q@���<��z��؟����cd��z�ˬT_u�Ѯ����&�z�k ��n ]�a%�py»�`Qd�xc������n�� ��*��oTd�;'j�<�!j���'�(~�ʹW�M� P�mȘ��@֨V+��R�`�$��`�+@��_[�kG����P���Zh9�R����&5b�v���Z���#p�&�Ա+��8�etZ7G���;��@"�e0���v7����?��z�?_���_�q1�T�"�p�ˎ/U 6_�B�>��0( ��}G#������Ȣ�p�� �9��;/& `�B&$�y��t(�*z�x���Ӕ������S�?Kȏ3���{p� b � ۍ-�z܈֦��6?<���ǬP�N�G �更� �6�/h�����0Z���������i�ua��e�*M'A� �x��v�q.>�F� oN{��Q���{gD��L��u��=|���O xN���d���q�8(��E�Uu��,��O� t�DJ ����;��G����e���C��VYZ�� ���T4{����(�Ӳ'c�t�f��w�c�jr�e�m �#7,�6��B�E4Q�P�.P�(&��^{9H-�m�o ��q�g1���=��>p�)/"p0!4�mS6ú�FN���h��D �)��XdT �FؤZ⸚�k���H�c8v� <���u�P�Հ���:��_�EN��|�ӛ��u?-�/�o�Lhk�ܸ�S�;�Rī�����T"�N����M��px7<�� j�$��`�Y)Pjh 5` K�Qf�4�C�bX"�D���;HD�Z�9R b�F)�UA����v�#��HD�!{������>I� �`�ԁ i�4�)t*�ç�Le�_���>ru�GEQg��ǔct��ō0��l6v���d�� ��GG8���v^�|�#JyZPSO�� Y�CuAߐ�"�x���OfHF@�K�V�!少Eҕ]h� ��[���)��.q����*0I<8��^�6�}p��^tho���ig�i����DK���p,��2�3�I��5����쓄OY�6s7Qs�Ow^�w�J/�A➰������0������g(Մ��y��Kԇ����QS��?H���w�X�=��ҞX�~���Q=�'���p?7�@g�~�G�}�r��g�T?���
One Hat Cyber Team
One Hat Cyber Team
Your IP :
3.141.196.30
Server IP :
162.0.235.113
Server :
Linux premium146.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software :
LiteSpeed
PHP Version :
5.6.40
Buat File
|
Buat Folder
Dir :
~
/
opt
/
alt
/
ruby25
/
lib64
/
ruby
/
2.5.0
/
View File Name :
open3.rb
# frozen_string_literal: true # # = open3.rb: Popen, but with stderr, too # # Author:: Yukihiro Matsumoto # Documentation:: Konrad Meyer # # Open3 gives you access to stdin, stdout, and stderr when running other # programs. # # # Open3 grants you access to stdin, stdout, stderr and a thread to wait for the # child process when running another program. # You can specify various attributes, redirections, current directory, etc., of # the program in the same way as for Process.spawn. # # - Open3.popen3 : pipes for stdin, stdout, stderr # - Open3.popen2 : pipes for stdin, stdout # - Open3.popen2e : pipes for stdin, merged stdout and stderr # - Open3.capture3 : give a string for stdin; get strings for stdout, stderr # - Open3.capture2 : give a string for stdin; get a string for stdout # - Open3.capture2e : give a string for stdin; get a string for merged stdout and stderr # - Open3.pipeline_rw : pipes for first stdin and last stdout of a pipeline # - Open3.pipeline_r : pipe for last stdout of a pipeline # - Open3.pipeline_w : pipe for first stdin of a pipeline # - Open3.pipeline_start : run a pipeline without waiting # - Open3.pipeline : run a pipeline and wait for its completion # module Open3 # Open stdin, stdout, and stderr streams and start external executable. # In addition, a thread to wait for the started process is created. # The thread has a pid method and a thread variable :pid which is the pid of # the started process. # # Block form: # # Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr| # pid = wait_thr.pid # pid of the started process. # ... # exit_status = wait_thr.value # Process::Status object returned. # } # # Non-block form: # # stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts]) # pid = wait_thr[:pid] # pid of the started process # ... # stdin.close # stdin, stdout and stderr should be closed explicitly in this form. # stdout.close # stderr.close # exit_status = wait_thr.value # Process::Status object returned. # # The parameters env, cmd, and opts are passed to Process.spawn. # A commandline string and a list of argument strings can be accepted as follows: # # Open3.popen3("echo abc") {|i, o, e, t| ... } # Open3.popen3("echo", "abc") {|i, o, e, t| ... } # Open3.popen3(["echo", "argv0"], "abc") {|i, o, e, t| ... } # # If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn. # # Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t| # p o.read.chomp #=> "/" # } # # wait_thr.value waits for the termination of the process. # The block form also waits for the process when it returns. # # Closing stdin, stdout and stderr does not wait for the process to complete. # # You should be careful to avoid deadlocks. # Since pipes are fixed length buffers, # Open3.popen3("prog") {|i, o, e, t| o.read } deadlocks if # the program generates too much output on stderr. # You should read stdout and stderr simultaneously (using threads or IO.select). # However, if you don't need stderr output, you can use Open3.popen2. # If merged stdout and stderr output is not a problem, you can use Open3.popen2e. # If you really need stdout and stderr output as separate strings, you can consider Open3.capture3. # def popen3(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end module_function :popen3 # Open3.popen2 is similar to Open3.popen3 except that it doesn't create a pipe for # the standard error stream. # # Block form: # # Open3.popen2([env,] cmd... [, opts]) {|stdin, stdout, wait_thr| # pid = wait_thr.pid # pid of the started process. # ... # exit_status = wait_thr.value # Process::Status object returned. # } # # Non-block form: # # stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts]) # ... # stdin.close # stdin and stdout should be closed explicitly in this form. # stdout.close # # See Process.spawn for the optional hash arguments _env_ and _opts_. # # Example: # # Open3.popen2("wc -c") {|i,o,t| # i.print "answer to life the universe and everything" # i.close # p o.gets #=> "42\n" # } # # Open3.popen2("bc -q") {|i,o,t| # i.puts "obase=13" # i.puts "6 * 9" # p o.gets #=> "42\n" # } # # Open3.popen2("dc") {|i,o,t| # i.print "42P" # i.close # p o.read #=> "*" # } # def popen2(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end module_function :popen2 # Open3.popen2e is similar to Open3.popen3 except that it merges # the standard output stream and the standard error stream. # # Block form: # # Open3.popen2e([env,] cmd... [, opts]) {|stdin, stdout_and_stderr, wait_thr| # pid = wait_thr.pid # pid of the started process. # ... # exit_status = wait_thr.value # Process::Status object returned. # } # # Non-block form: # # stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts]) # ... # stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form. # stdout_and_stderr.close # # See Process.spawn for the optional hash arguments _env_ and _opts_. # # Example: # # check gcc warnings # source = "foo.c" # Open3.popen2e("gcc", "-Wall", source) {|i,oe,t| # oe.each {|line| # if /warning/ =~ line # ... # end # } # } # def popen2e(*cmd, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end module_function :popen2e def popen_run(cmd, opts, child_io, parent_io) # :nodoc: if last = Hash.try_convert(cmd.last) opts = opts.merge(last) cmd.pop end pid = spawn(*cmd, opts) wait_thr = Process.detach(pid) child_io.each(&:close) result = [*parent_io, wait_thr] if defined? yield begin return yield(*result) ensure parent_io.each(&:close) wait_thr.join end end result end module_function :popen_run class << self private :popen_run end # Open3.capture3 captures the standard output and the standard error of a command. # # stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts]) # # The arguments env, cmd and opts are passed to Open3.popen3 except # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn. # # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input. # # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode. # # Examples: # # # dot is a command of graphviz. # graph = <<'End' # digraph g { # a -> b # } # End # drawn_graph, dot_log = Open3.capture3("dot -v", :stdin_data=>graph) # # o, e, s = Open3.capture3("echo abc; sort >&2", :stdin_data=>"foo\nbar\nbaz\n") # p o #=> "abc\n" # p e #=> "bar\nbaz\nfoo\n" # p s #=> #<Process::Status: pid 32682 exit 0> # # # generate a thumbnail image using the convert command of ImageMagick. # # However, if the image is really stored in a file, # # system("convert", "-thumbnail", "80", "png:#{filename}", "png:-") is better # # because of reduced memory consumption. # # But if the image is stored in a DB or generated by the gnuplot Open3.capture2 example, # # Open3.capture3 should be considered. # # # image = File.read("/usr/share/openclipart/png/animals/mammals/sheep-md-v0.1.png", :binmode=>true) # thumbnail, err, s = Open3.capture3("convert -thumbnail 80 png:- png:-", :stdin_data=>image, :binmode=>true) # if s.success? # STDOUT.binmode; print thumbnail # end # def capture3(*cmd, stdin_data: '', binmode: false, **opts) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end module_function :capture3 # Open3.capture2 captures the standard output of a command. # # stdout_str, status = Open3.capture2([env,] cmd... [, opts]) # # The arguments env, cmd and opts are passed to Open3.popen3 except # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn. # # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input. # # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode. # # Example: # # # factor is a command for integer factorization. # o, s = Open3.capture2("factor", :stdin_data=>"42") # p o #=> "42: 2 3 7\n" # # # generate x**2 graph in png using gnuplot. # gnuplot_commands = <<"End" # set terminal png # plot x**2, "-" with lines # 1 14 # 2 1 # 3 8 # 4 5 # e # End # image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true) # def capture2(*cmd, stdin_data: nil, binmode: false, **opts) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end module_function :capture2 # Open3.capture2e captures the standard output and the standard error of a command. # # stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts]) # # The arguments env, cmd and opts are passed to Open3.popen3 except # <code>opts[:stdin_data]</code> and <code>opts[:binmode]</code>. See Process.spawn. # # If <code>opts[:stdin_data]</code> is specified, it is sent to the command's standard input. # # If <code>opts[:binmode]</code> is true, internal pipes are set to binary mode. # # Example: # # # capture make log # make_log, s = Open3.capture2e("make") # def capture2e(*cmd, stdin_data: nil, binmode: false, **opts) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end module_function :capture2e # Open3.pipeline_rw starts a list of commands as a pipeline with pipes # which connect to stdin of the first command and stdout of the last command. # # Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) {|first_stdin, last_stdout, wait_threads| # ... # } # # first_stdin, last_stdout, wait_threads = Open3.pipeline_rw(cmd1, cmd2, ... [, opts]) # ... # first_stdin.close # last_stdout.close # # Each cmd is a string or an array. # If it is an array, the elements are passed to Process.spawn. # # cmd: # commandline command line string which is passed to a shell # [env, commandline, opts] command line string which is passed to a shell # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) # # Note that env and opts are optional, as for Process.spawn. # # The options to pass to Process.spawn are constructed by merging # +opts+, the last hash element of the array, and # specifications for the pipes between each of the commands. # # Example: # # Open3.pipeline_rw("tr -dc A-Za-z", "wc -c") {|i, o, ts| # i.puts "All persons more than a mile high to leave the court." # i.close # p o.gets #=> "42\n" # } # # Open3.pipeline_rw("sort", "cat -n") {|stdin, stdout, wait_thrs| # stdin.puts "foo" # stdin.puts "bar" # stdin.puts "baz" # stdin.close # send EOF to sort. # p stdout.read #=> " 1\tbar\n 2\tbaz\n 3\tfoo\n" # } def pipeline_rw(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end module_function :pipeline_rw # Open3.pipeline_r starts a list of commands as a pipeline with a pipe # which connects to stdout of the last command. # # Open3.pipeline_r(cmd1, cmd2, ... [, opts]) {|last_stdout, wait_threads| # ... # } # # last_stdout, wait_threads = Open3.pipeline_r(cmd1, cmd2, ... [, opts]) # ... # last_stdout.close # # Each cmd is a string or an array. # If it is an array, the elements are passed to Process.spawn. # # cmd: # commandline command line string which is passed to a shell # [env, commandline, opts] command line string which is passed to a shell # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) # # Note that env and opts are optional, as for Process.spawn. # # Example: # # Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz", # [{"LANG"=>"C"}, "grep", "GET /favicon.ico"], # "logresolve") {|o, ts| # o.each_line {|line| # ... # } # } # # Open3.pipeline_r("yes", "head -10") {|o, ts| # p o.read #=> "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\n" # p ts[0].value #=> #<Process::Status: pid 24910 SIGPIPE (signal 13)> # p ts[1].value #=> #<Process::Status: pid 24913 exit 0> # } # def pipeline_r(*cmds, **opts, &block) out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end module_function :pipeline_r # Open3.pipeline_w starts a list of commands as a pipeline with a pipe # which connects to stdin of the first command. # # Open3.pipeline_w(cmd1, cmd2, ... [, opts]) {|first_stdin, wait_threads| # ... # } # # first_stdin, wait_threads = Open3.pipeline_w(cmd1, cmd2, ... [, opts]) # ... # first_stdin.close # # Each cmd is a string or an array. # If it is an array, the elements are passed to Process.spawn. # # cmd: # commandline command line string which is passed to a shell # [env, commandline, opts] command line string which is passed to a shell # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) # # Note that env and opts are optional, as for Process.spawn. # # Example: # # Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|i, ts| # i.puts "hello" # } # def pipeline_w(*cmds, **opts, &block) in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end module_function :pipeline_w # Open3.pipeline_start starts a list of commands as a pipeline. # No pipes are created for stdin of the first command and # stdout of the last command. # # Open3.pipeline_start(cmd1, cmd2, ... [, opts]) {|wait_threads| # ... # } # # wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts]) # ... # # Each cmd is a string or an array. # If it is an array, the elements are passed to Process.spawn. # # cmd: # commandline command line string which is passed to a shell # [env, commandline, opts] command line string which is passed to a shell # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) # # Note that env and opts are optional, as for Process.spawn. # # Example: # # # Run xeyes in 10 seconds. # Open3.pipeline_start("xeyes") {|ts| # sleep 10 # t = ts[0] # Process.kill("TERM", t.pid) # p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)> # } # # # Convert pdf to ps and send it to a printer. # # Collect error message of pdftops and lpr. # pdf_file = "paper.pdf" # printer = "printer-name" # err_r, err_w = IO.pipe # Open3.pipeline_start(["pdftops", pdf_file, "-"], # ["lpr", "-P#{printer}"], # :err=>err_w) {|ts| # err_w.close # p err_r.read # error messages of pdftops and lpr. # } # def pipeline_start(*cmds, **opts, &block) if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end module_function :pipeline_start # Open3.pipeline starts a list of commands as a pipeline. # It waits for the completion of the commands. # No pipes are created for stdin of the first command and # stdout of the last command. # # status_list = Open3.pipeline(cmd1, cmd2, ... [, opts]) # # Each cmd is a string or an array. # If it is an array, the elements are passed to Process.spawn. # # cmd: # commandline command line string which is passed to a shell # [env, commandline, opts] command line string which is passed to a shell # [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell) # [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell) # # Note that env and opts are optional, as Process.spawn. # # Example: # # fname = "/usr/share/man/man1/ruby.1.gz" # p Open3.pipeline(["zcat", fname], "nroff -man", "less") # #=> [#<Process::Status: pid 11817 exit 0>, # # #<Process::Status: pid 11820 exit 0>, # # #<Process::Status: pid 11828 exit 0>] # # fname = "/usr/share/man/man1/ls.1.gz" # Open3.pipeline(["zcat", fname], "nroff -man", "colcrt") # # # convert PDF to PS and send to a printer by lpr # pdf_file = "paper.pdf" # printer = "printer-name" # Open3.pipeline(["pdftops", pdf_file, "-"], # ["lpr", "-P#{printer}"]) # # # count lines # Open3.pipeline("sort", "uniq -c", :in=>"names.txt", :out=>"count") # # # cyclic pipeline # r,w = IO.pipe # w.print "ibase=14\n10\n" # Open3.pipeline("bc", "tee /dev/tty", :in=>r, :out=>w) # #=> 14 # # 18 # # 22 # # 30 # # 42 # # 58 # # 78 # # 106 # # 202 # def pipeline(*cmds, **opts) pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end module_function :pipeline def pipeline_run(cmds, pipeline_opts, child_io, parent_io) # :nodoc: if cmds.empty? raise ArgumentError, "no commands" end opts_base = pipeline_opts.dup opts_base.delete :in opts_base.delete :out wait_thrs = [] r = nil cmds.each_with_index {|cmd, i| cmd_opts = opts_base.dup if String === cmd cmd = [cmd] else cmd_opts.update cmd.pop if Hash === cmd.last end if i == 0 if !cmd_opts.include?(:in) if pipeline_opts.include?(:in) cmd_opts[:in] = pipeline_opts[:in] end end else cmd_opts[:in] = r end if i != cmds.length - 1 r2, w2 = IO.pipe cmd_opts[:out] = w2 else if !cmd_opts.include?(:out) if pipeline_opts.include?(:out) cmd_opts[:out] = pipeline_opts[:out] end end end pid = spawn(*cmd, cmd_opts) wait_thrs << Process.detach(pid) r.close if r w2.close if w2 r = r2 } result = parent_io + [wait_thrs] child_io.each(&:close) if defined? yield begin return yield(*result) ensure parent_io.each(&:close) wait_thrs.each(&:join) end end result end module_function :pipeline_run class << self private :pipeline_run end end