බහු විධානයන්ට stdout යැවිය හැක්කේ කෙසේද?


203

ආදානය මත පෙරහන් කරන හෝ ක්‍රියා කරන සමහර විධානයන් ඇත, පසුව එය ප්‍රතිදානය ලෙස සම්මත කරයි, මම සාමාන්‍යයෙන් සිතන්නේ stdout- නමුත් සමහර විධානයන් එය රැගෙන stdinඔවුන් සමඟ කරන ඕනෑම දෙයක් කරනු ඇති අතර කිසිවක් ප්‍රතිදානය නොකරයි.

මම OS X මෙහෙයුම් පද්ධතිය සමග වඩාත් හුරු පුරුදු ඉන්නේ එසේ වූ වහාම මතකයට එන දෙකක් තිබේ pbcopyහා pbpaste- පද්ධතිය අලවන්න ප්රවේශ මාර්ගයෙන් වන.

කෙසේ වෙතත්, මම දන්නවා මට stdout ගෙන ප්‍රතිදානය කෙළ ගසා stdoutගොනුවකට සහ ගොනුවකට යාමට අවශ්‍ය නම් මට teeවිධානය භාවිතා කළ හැකිය . මම ඒ ගැන ටිකක් දනිමි xargs, නමුත් මම සොයන්නේ එය යැයි මම නොසිතමි.

stdoutවිධාන දෙකක් (හෝ වැඩි ගණනක්) අතරට යාමට මට බෙදිය හැක්කේ කෙසේදැයි දැන ගැනීමට මට අවශ්‍යය . උදාහරණයක් වශයෙන්:

cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors

ඊට වඩා හොඳ උදාහරණයක් බොහෝ විට ඇත, නමුත් මම එය උනන්දු වන්නේ එය විකාශනය නොකරන විධානයකට stdout යැවිය හැකි ආකාරය දැන ගැනීමට සහ stdout"නිශ්ශබ්ද" නොවී සිටීමටයි - මම catගොනුවක් කරන්නේ කෙසේද යන්න ගැන විමසන්නේ නැත grepඑහි කොටසක් සහ එය ක්ලිප් පුවරුවට පිටපත් කරන්න - විශේෂිත විධානයන් එතරම් වැදගත් නොවේ.

එසේම - මම මෙය ගොනුවකට යවන්නේ කෙසේදැයි stdoutඅසන්නේ නැත - මෙය "අනුපිටපත්" ප්‍රශ්නයක් විය හැකිය (සමාවෙන්න) නමුත් මම යම්කිසි සොයා බැලීමක් කළ අතර stdout සහ ගොනුව අතර බෙදීම් ගැන විමසන සමාන ප්‍රශ්න පමණක් සොයාගත හැකි විය. - සහ එම ප්‍රශ්නවලට පිළිතුරු teeමට වැඩ කරයි කියා මම නොසිතමි.

අවසාන වශයෙන්, ඔබට ඇසිය හැකිය "ඇයි නල දාමයේ අන්තිම දේ pbcopy කරන්න නැත්තේ?" මගේ ප්‍රතිචාරය 1) මට එය භාවිතා කිරීමට අවශ්‍ය නම් සහ කොන්සෝලය තුළ ප්‍රතිදානය තවමත් දැකීමට අවශ්‍ය නම් කුමක් කළ යුතුද? 2) stdoutආදානය සැකසූ පසු ප්‍රතිදානය නොකරන විධාන දෙකක් භාවිතා කිරීමට මට අවශ්‍ය නම් කුමක් කළ යුතුද ?

ඔහ්, සහ තවත් එක් දෙයක් - මට භාවිතා කළ හැකි බව teeසහ නම් කරන ලද පයිප්පයක් ( mkfifo) නමුත් මම සිතුවේ මෙය පෙර සැකසුමකින් තොරව පේළිගතව, සංක්ෂිප්තව කළ හැකි ක්‍රමයක් ගැනයි :)


Answers:


255

මේ සඳහා ඔබට teeආදේශක භාවිතා කළ හැකිය .

cat file.txt | tee >(pbcopy) | grep errors

මෙය සියලු ප්‍රතිදානයන් වෙත යවනු ඇති cat file.txtඅතර pbcopy, ඔබට ලැබෙන්නේ grepඔබේ කොන්සෝලයෙහි ප්‍රති result ලය පමණි .

ඔබට teeකොටසෙහි බහු ක්‍රියාදාමයන් තැබිය හැකිය :

cat file.txt | tee >(pbcopy) >(do_stuff) >(do_more_stuff) | grep errors

22
සැලකිලිමත් වීමක් pbcopyනොව පොදුවේ සඳහන් කිරීම වටී: ක්‍රියාවලි ආදේශන ප්‍රතිදානය කුමක් වුවත් මුල් ආදානයෙන් පසුව ඊළඟ නල කොටස දැකිය හැකිය; උදා: seq 3 | tee >(cat -n) | cat -e( cat -nආදාන රේඛා අංකනය කිරීම, cat -eනව රේඛා සමඟ සලකුණු කිරීම $; cat -eමුල් ආදානය (පළමුව) සහ (ඉන්පසු) ප්‍රතිදානය යන දෙකටම එය අදාළ වන බව ඔබට පෙනෙනු cat -nඇත. බහුවිධ ක්‍රියාවලි ආදේශක වලින් ප්‍රතිදානය නිර්ණය නොවන අනුපිළිවෙලට පැමිණේ.
mklement0

53
මෙම >(පමණක් ක්රියා කරයි bash. උදාහරණයක් ලෙස ඔබ එය උත්සාහ කළහොත් shඑය ක්‍රියා නොකරනු ඇත. මෙම දැන්වීම වැදගත් ය.
AAlvz

11
@AAlvz: ඔහු හොඳ: ක්රියාවලිය ආදේශ කිරීම යි නො වූ POSIX ලක්ෂණය; dash, shඋබුන්ටු මත ක්‍රියා කරන , එයට සහය නොදක්වන අතර, ක්‍රියාත්මක වන shවිට හෝ ක්‍රියාත්මක වන විට බාෂ් පවා විශේෂාංගය අක්‍රිය set -o posixකරයි. කෙසේ වෙතත්, එය ක්‍රියාවලි ආදේශක සඳහා සහය දක්වන්නේ බාෂ් පමණක් නොවේ: kshසහ zshඒවාටද සහාය දෙන්න (අනෙක් අය ගැන විශ්වාස නැත).
mklement0

2
true mklement0 එය සත්‍ය නොවන බව පෙනේ. Zsh (උබුන්ටු 14.04) හි ඔබේ පේළිය මුද්‍රණය කරයි: 1 1 2 2 3 3 1 $ 2 $ 3 $ එය කනගාටුවට කරුණකි, මන්ද ඔබ කියන ආකාරයට ක්‍රියාකාරීත්වය මට අවශ්‍ය විය.
අක්තෝ

2
K අක්ටාවෝ: ඇත්ත වශයෙන්ම, මගේ නියැදි විධානය ක්‍රියාත්මක වන්නේ විස්තර කර ඇති ආකාරයට පමණක් වන bashඅතර ksh- zshපෙනෙන ආකාරයට නිමැවුම් ක්‍රියාවලි ආදේශක වලින් නල මාර්ගයෙන් ප්‍රතිදානය යවන්නේ නැත (තර්කානුකූලව, එය වඩාත් සුදුසුය , මන්ද එය ඊළඟ නල මාර්ගයට යවන දේ දූෂණය නොකරන බැවිනි - එය තවමත් මුද්‍රණය කරයි ). දී සියලු කටු සඳහන්, කෙසේ වෙතත්, එය සාමාන්යයෙන් නොවන ක්රියාවලිය ආෙද්ශක සිට නිත්ය stdout ප්රතිදාන සහ ප්රතිදානය මිශ්ර වන තනි නල කිරීම හොඳ අදහසක් - ප්රතිදාන ඇනවුම් කිරීම පමණක් සිදු වන්නේ බොහෝ කලාතුරකින් වන හෝ විශාල සමග මතු විය හැක අයුරින්, පෙරදැකිය හැකි වනු ඇත ප්‍රතිදාන දත්ත කට්ටල.
mklement0

135

ඔබට බහු ගොනු නාමයන් නියම කළ හැකි teeඅතර, ඊට අමතරව සම්මත ප්‍රතිදානය එක් විධානයකට ඇතුළත් කළ හැකිය. ප්‍රතිදානය බහු විධානයන් වෙත යැවීම සඳහා, ඔබට බහු පයිප්ප සෑදිය යුතු අතර ඒවා එක් එක් ප්‍රතිදානයක් ලෙස සඳහන් කළ යුතුය tee. මෙය කිරීමට ක්‍රම කිහිපයක් තිබේ.

ක්‍රියාවලි ආදේශනය

ඔබේ කවචය ksh93, bash හෝ zsh නම්, ඔබට ක්‍රියාවලි ආදේශනය භාවිතා කළ හැකිය. මෙය ගොනු නාමයක් අපේක්ෂා කරන විධානයකට පයිප්පයක් යැවීමේ ක්‍රමයකි. කවචය නළය නිර්මාණය /dev/fd/3කර විධානයට සමාන ගොනු නාමයක් ලබා දෙයි. අංකය යනු පයිප්පයට සම්බන්ධ කර ඇති ගොනු විස්තරයයි . සමහර යුනික්ස් ප්‍රභේද සහාය නොදක්වයි /dev/fd; මේවා මත නම් කරන ලද පයිප්පයක් භාවිතා කරයි (පහත බලන්න).

tee >(command1) >(command2) | command3

ගොනු විස්තර කරන්නන්

ඕනෑම POSIX කවචයක, ඔබට පැහැදිලිවම ගොනු විස්තර කිහිපයක් භාවිතා කළ හැකිය . මේ සඳහා සහාය වන යුනික්ස් ප්‍රභේදයක් අවශ්‍ය වේ /dev/fd, මන්දයත් එක් ප්‍රතිදානයක් හැර අන් සියල්ලම teeනමෙන් නියම කළ යුතු බැවිනි.

{ { { tee /dev/fd/3 /dev/fd/4 | command1 >&9;
    } 3>&1 | command2 >&9;
  } 4>&1 | command3 >&9;
} 9>&1

නම් කරන ලද පයිප්ප

වඩාත්ම මූලික හා අතේ ගෙන යා හැකි ක්‍රමය නම් කරන ලද පයිප්ප භාවිතා කිරීමයි . අවාසිය නම් ඔබට ලිවිය හැකි නාමාවලියක් සොයා ගැනීම, පයිප්ප සෑදීම සහ පසුව පිරිසිදු කිරීම අවශ්‍ය වේ.

tmp_dir=$(mktemp -d)
mkfifo "$tmp_dir/f1" "$tmp_dir/f2"
command1 <"$tmp_dir/f1" & pid1=$!
command2 <"$tmp_dir/f2" & pid2=$!
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
rm -rf "$tmp_dir"
wait $pid1 $pid2

10
බාෂ් හෝ එක්තරා ksh මත විශ්වාසය තැබීමට අකමැති අයට විකල්ප අනුවාද දෙක ලබා දීම ගැන ඔබට ස්තූතියි.
trr

tee "$tmp_dir/f1" "$tmp_dir/f2" | command3නියත වශයෙන්ම command3 | tee "$tmp_dir/f1" "$tmp_dir/f2"ඔබට අවශ්‍ය පරිදි command3නල මාර්ගයක් තිබිය teeයුතුද? මම යටතේ ඔබේ අනුවාදය පරීක්ෂා dashහා teeදින නියමයක් නොමැතිව ආදාන බලා, නමුත් බලාපොරොත්තු ප්රතිඵලයක් නිෂ්පාදනය කරන පිණිස මාරු කුට්ටි.
ඒඩ්‍රියන් ගුන්ටර්

1
Rian ඇඩ්‍රියන්ගුන්ටර් අංක. උදාහරණ තුනම සම්මත ආදානයෙන් දත්ත කියවා එය එක් එක් වෙත යවයි command, command2සහ command3.
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

Il ගිලස් මා දකින පරිදි, මම එහි අභිප්‍රාය වැරදි ලෙස අර්ථකථනය කර ස්නිපටය වැරදි ලෙස භාවිතා කිරීමට උත්සාහ කළෙමි. පැහැදිලි කිරීම සඳහා ස්තූතියි!
ඒඩ්‍රියන් ගුන්ටර්

භාවිතා කරන කවචය මත ඔබට පාලනයක් නොමැති නම්, නමුත් ඔබට පැහැදිලිවම බාෂ් භාවිතා කළ හැකිය, ඔබට එය කළ හැකිය <command> | bash -c 'tee >(command1) >(command2) | command3'. එය මගේ නඩුවට උදව් විය.
gc5

17

ක්‍රියාවලි ආදේශනය සමඟ සෙල්ලම් කරන්න.

mycommand_exec |tee >(grep ook > ook.txt) >(grep eek > eek.txt)

grepද්විමය ද්විමය mycommand_execයනු ඒවායේ ක්‍රියාවලි නිශ්චිත ආදානයට සමාන ප්‍රතිදානයක් ඇති ද්විමය දෙකකි .


17

ඔබ භාවිතා කරන්නේ zshනම් ඔබට MULTIOSවිශේෂාංගයේ බලයෙන් ප්‍රයෝජන ගත හැකිය , එනම් teeවිධානය සම්පූර්ණයෙන්ම ඉවත් කරන්න :

uname >file1 >file2

ප්‍රතිදානය unameවෙනස් ගොනු දෙකකට ලියනු ඇත : file1සහ file2, සමාන දේuname | tee file1 >file2

ඒ හා සමානව සම්මත යෙදවුම් නැවත හරවා යැවීම

wc -l <file1 <file2

සමාන වේ cat file1 file2 | wc -l(කරුණාකර මෙය සමාන නොවන බව කරුණාවෙන් සලකන්න wc -l file1 file2, පසුව එක් එක් ගොනුවේ පේළි ගණන වෙන වෙනම ගණන් කරයි).

MULTIOSක්‍රියාවලි ආදේශනය භාවිතා කරමින් ප්‍රතිදානය ලිපිගොනු වෙත නොව වෙනත් ක්‍රියාවලීන් වෙත හරවා යැවීමට ඔබට භාවිතා කළ හැකිය .

echo abc > >(grep -o a) > >(tr b x) > >(sed 's/c/y/')

3
දැන ගැනීමට ලැබීම සතුටක්. පෙරනිමියෙන් MULTIOSක්‍රියාත්මක වන විකල්පයකි (සහ එය අක්‍රිය කළ හැකිය unsetopt MULTIOS).
mklement0

7

විධානයකින් නිපදවන සුළු නිමැවුමක් සඳහා, අපට ප්‍රතිදානය තාවකාලික ගොනුවකට හරවා යැවිය හැකි අතර, එම තාවකාලික ගොනුව විධාන වෙත ලූපයේ යැවිය හැකිය. ක්‍රියාත්මක විධාන අනුපිළිවෙල වැදගත් වන විට මෙය ප්‍රයෝජනවත් වේ.

උදාහරණයක් ලෙස පහත දැක්වෙන පිටපතට එය කළ හැකිය:

#!/bin/sh

temp=$( mktemp )
cat /dev/stdin > "$temp"

for arg
do
    eval "$arg" < "$temp"
done
rm "$temp"

ෂෙල් /bin/shලෙස උබුන්ටු 16.04 හි පරීක්ෂණ ධාවනය dash:

$ cat /etc/passwd | ./multiple_pipes.sh  'wc -l'  'grep "root"'                                                          
48
root:x:0:0:root:/root:/bin/bash

5

විධානය STDOUTවිචල්‍යයකට ග්‍රහණය කර ඔබ කැමති වාර ගණනක් නැවත භාවිතා කරන්න:

commandoutput="$(command-to-run)"
echo "$commandoutput" | grep -i errors
echo "$commandoutput" | pbcopy

ඔබටත් ග්‍රහණය කර ගැනීමට අවශ්‍ය නම් , විධානය අවසානයේ STDERRභාවිතා 2>&1කරන්න:

commandoutput="$(command-to-run 2>&1)"

3
විචල්යයන් ගබඩා කර ඇත්තේ කොහේද? ඔබ විශාල ලිපිගොනුවක් හෝ ඒ හා සමාන දෙයක් සමඟ කටයුතු කරන්නේ නම්, මෙය විශාල මතකයක් ලබා නොගනීද? විචල්යයන් ප්රමාණයෙන් සීමිතද?
cwd

1
$ විධාන ප්‍රතිදානය අති විශාල නම් කුමක් කළ යුතුද?
නිඛිල් මුලි

4
නිසැකවම මෙම විසඳුම ලබා ගත හැක්කේ ප්‍රතිදානයේ ප්‍රමාණය පහසුවෙන් මතකයට ගැලපෙන බව ඔබ දන්නා විට පමණක් වන අතර, ඊළඟ විධානයන් ක්‍රියාත්මක කිරීමට පෙර සම්පූර්ණ ප්‍රතිදානයම බෆර් කිරීම සමඟ ඔබ හොඳින් සිටී. පයිප්ප මෙම ගැටළු දෙක නිරාකරණය කරන්නේ අත්තනෝමතික දිග දත්ත වලට ඉඩ දී එය උත්පාදනය වන විට එය ග්‍රාහකයාට තථ්‍ය කාලීනව ප්‍රවාහනය කිරීමෙනි.
trr

2
ඔබට කුඩා නිමැවුමක් තිබේ නම් මෙය හොඳ විසඳුමක් වන අතර ප්‍රතිදානය පෙළ නොවන අතර ද්විමය නොවන බව ඔබ දන්නවා. (ෂෙල් විචල්‍යයන් බොහෝ විට ද්විමය ආරක්ෂිත නොවේ)
Rucent88

1
ද්විමය දත්ත සමඟ වැඩ කිරීමට මට මෙය ලබා ගත නොහැක. මම හිතන්නේ එය ප්‍රතිරාවය සමඟ ශුන්‍ය බයිට් හෝ වෙනත් අක්ෂර නොවන දත්ත අර්ථ නිරූපණය කිරීමට උත්සාහ කරයි.
රොල්ෆ්

2

ද පවතී peeසිට moreutils පැකේජය. එය ඒ සඳහා නිර්මාණයකි: pee 'command1' 'command2' 'cat -'


1

මෙය ප්‍රයෝජනවත් විය හැකිය: http://www.spinellis.gr/sw/dgsh/ (යොමු කරන ලද ප්‍රස්ථාර කවචය) “බහුකාර්ය” විධානයන් සඳහා පහසු වාක්‍ය ඛණ්ඩයකට සහය දක්වන කඩිනම් ආදේශකයක් සේ පෙනේ.


0

මෙන්න ඕනෑම කවචයක් සමඟ අනුකූල වන ඉක්මන් හා අපිරිසිදු අර්ධ විසඳුමක් busybox.

එය විසඳන වඩාත් පටු ගැටළුව නම්: stdoutතාවකාලික ලිපිගොනු හෝ නම් කරන ලද පයිප්ප නොමැතිව සම්පූර්ණය එක් කොන්සෝලයකට මුද්‍රණය කර තවත් එකක් මත පෙරීම කරන්න.

  • එකම සත්කාරකයට තවත් සැසියක් ආරම්භ කරන්න. එහි TTY නම සොයා ගැනීමට ටයිප් කරන්න tty. අපි උපකල්පනය කරමු /dev/pty/2.
  • පළමු සැසියේදී ධාවනය කරන්න the_program | tee /dev/pty/2 | grep ImportantLog:

ඔබට එක් සම්පූර්ණ ලොගයක් සහ පෙරහන් කළ එකක් ලැබේ.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.