OSX bash, คำสั่ง 'watch'


292

ฉันกำลังมองหาวิธีที่ดีที่สุดในการทำซ้ำคำสั่ง 'watch' Linux บน Mac OSX ฉันต้องการเรียกใช้คำสั่งทุกสองสามวินาทีเพื่อจับคู่รูปแบบกับเนื้อหาของไฟล์เอาต์พุตโดยใช้ 'tail' และ 'sed'

ตัวเลือกที่ดีที่สุดของฉันใน Mac คืออะไรและสามารถทำได้โดยไม่ต้องดาวน์โหลดซอฟต์แวร์


2
ทำไมคุณต้องการทำซ้ำเมื่อคุณสามารถติดตั้งได้
Andrew Marshall

3
เพราะฉันต้องกำหนดค่า Macs ทั้งหมดในสำนักงานที่ใช้สคริปต์ของฉัน
joseph.hainline

ฉันอยากจะแนะนำว่าสคริปต์ของคุณติดตั้งชงแล้วดู
AsTeR

Brew's Watch ดูเหมือนจะไม่รับคำสั่งในเส้นทางหรือนามแฝงของฉัน
sam boosalis

อีกทางเลือกหนึ่งสำหรับคำสั่งคุณสามารถใช้แอพพลิเคชั่น /Applications/Utilities/Console.app เพื่อตรวจสอบล็อกไฟล์ อนุญาตให้กรองด้วยการค้นหาขั้นพื้นฐาน
JuanMa Cuevas

คำตอบ:


336

คุณสามารถเลียนแบบฟังก์ชันการทำงานขั้นพื้นฐานได้ด้วย shell loop

while :; do clear; your_command; sleep 2; done

ที่จะวนซ้ำตลอดไปล้างหน้าจอเรียกใช้คำสั่งของคุณและรอสองวินาที - การwatch your_commandใช้งานขั้นพื้นฐาน

คุณสามารถทำขั้นตอนนี้เพิ่มเติมและสร้างwatch.shสคริปต์ที่สามารถยอมรับyour_commandและsleep_durationเป็นพารามิเตอร์:

#!/bin/bash
# usage: watch.sh <your_command> <sleep_duration>

while :; 
  do 
  clear
  date
  $1
  sleep $2
done

2
ฉันเชื่อว่านาฬิกาจะแสดงเฉพาะหน้าจอแรกของเอาต์พุต หากคุณต้องการทำสิ่งที่คล้ายกันให้เปลี่ยนyour_commandเป็นyour_command 2>&1|head -10
Mark Eirich

10
มันใช้งานได้ดี แต่ฉันชอบที่sleep ${2:-1}จะเลือกช่วงเวลา
Daniel Lubarov

2
นอกจากนี้มันecho "$(date)"เทียบเท่ากับdate?
Daniel Lubarov

5
มันไม่ทำงานกับท่อ นี่คือทางแยกที่มีการปรับปรุงหลายอย่าง: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov

ไม่ทำงานเหมือนwatchเมื่อเอาต์พุตมีมากกว่าหนึ่งหน้าจอ แสดงเฉพาะจุดจบในขณะที่watchแสดงเฉพาะส่วนบนเท่านั้น (ไม่เหมาะ)
h__

546

ด้วยการติดตั้งHomebrew :

brew install watch


23
วิธีไปอย่างแน่นอนถ้าคุณใช้brewกับ mac
Maxence

2
รายละเอียดเพิ่มเติมจะได้รับการชื่นชม เมื่อฉันค้นหา "brew watch osx" นี่คือผลการค้นหายอดนิยม แก้ไข: เห็นได้ชัดว่ามันเป็นคำสั่ง Linux สำหรับผู้ที่ไม่แน่ใจว่าจะใช้งานอย่างไรwatch: stackoverflow.com/questions/13593771/…
gwg

2
สิ่งนี้watchจากการชงดูเหมือนจะไม่อ่านนามแฝงของผู้ใช้ เมื่อเรียกใช้watch somealiasงานฉันไม่พบคำสั่ง
RNickMcCandless

@NickMc วิธีที่เหมาะสมในการใช้ watch คือการทำwatch [command]เมื่อคุณใช้watch somealiasมันโดยถือว่าsomealiasเป็นคำสั่งที่คุณสามารถเรียกใช้ในเทอร์มินัลของคุณ
seantomburke

38

ใช้macports :

$ sudo port install watch

3
ไม่มีวิธีที่ดีกว่าแล้วใช้watchคำสั่งโดยตรง
โอลิเวอร์

8
เหตุใดจึงใช้ชงแทน MacPorts
bmauter

1
@bmauter ต่อตนเอง: stackoverflow.com/questions/21374366/…
CenterOrbit

4
@CenterOrbit นั่นคือเหตุผลที่ฉันถาม @ joseph.hainline บอกว่าไม่ใช้ MacPorts แต่ไม่ได้ระบุว่าทำไม เป็นwatchคำสั่งที่ถูกจับใน MacPorts?
bmauter

มันไม่ถูกจับ นั่นเป็นคำแนะนำที่แย่มาก MacPort ใช้งานได้ดีและมีแพ็คเกจมากมาย ใช้มัน.
Ali Gangji

16

กระสุนด้านบนจะทำเคล็ดลับคุณสามารถแปลงให้เป็นนามแฝงได้ (อาจจำเป็นต้องห่อในฟังก์ชันเพื่อจัดการพารามิเตอร์)

alias myWatch='_() { while :; do clear; $2; sleep $1; done }; _'

ตัวอย่าง:

myWatch 1 ls ## self-explanatory
myWatch 5 "ls -lF $HOME" ## every 5 seconds, list out home dir; double-quotes around command to keep its args together

อีกทางเลือกหนึ่งคือ homebrew สามารถติดตั้งนาฬิกาได้จากhttp://procps.sourceforge.net/

brew install watch

14

อาจเป็นได้ว่า "ดู" ไม่ใช่สิ่งที่คุณต้องการ คุณอาจต้องการขอความช่วยเหลือในการแก้ปัญหาของคุณไม่ใช่ในการใช้โซลูชันของคุณ! :)

หากเป้าหมายที่แท้จริงของคุณคือเรียกการกระทำตามสิ่งที่เห็นจากtailคำสั่งคุณสามารถทำได้โดยเป็นส่วนหนึ่งของส่วนท้าย แทนการทำงาน "เป็นระยะ ๆ" ซึ่งเป็นสิ่งที่watchไม่คุณสามารถเรียกใช้รหัสของคุณเกี่ยวกับความต้องการ

#!/bin/sh

tail -F /var/log/somelogfile | while read line; do
  if echo "$line" | grep -q '[Ss]ome.regex'; then
    # do your stuff
  fi
done

โปรดทราบว่าtail -Fจะยังคงติดตามไฟล์บันทึกต่อไปแม้ว่าจะได้รับการหมุนเวียนโดย newsyslog หรือ logrotate tail -fคุณต้องการที่จะใช้วิธีนี้แทนกรณีที่ต่ำกว่า ตรวจสอบman tailรายละเอียด

หากคุณต้องการรันคำสั่งเป็นระยะ ๆ คำตอบอื่น ๆ ที่ให้ไว้สามารถเปลี่ยนเป็นเชลล์สคริปต์แบบสั้นได้:

#!/bin/sh
if [ -z "$2" ]; then
  echo "Usage: $0 SECONDS COMMAND" >&2
  exit 1
fi

SECONDS=$1
shift 1
while sleep $SECONDS; do
  clear
  $*
done

น่าเสียดายที่เชลล์สคริปต์นี้ใช้ไม่ได้กับพารามิเตอร์ที่ขยาย bash เช่น: watch 2 cat *
ผู้บัญชาการรหัส

1
@CodeCommander - บรรทัดคำสั่งwatch 2 cat *จะขยายพารามิเตอร์ก่อนเรียกใช้สคริปต์ดังนั้นในไดเรกทอรีที่มีไฟล์ "foo" และ "bar" คุณจะเรียกใช้cat foo barทุก 2 วินาที คุณคาดหวังพฤติกรรมอะไร
ghoti

@ghoti ฉันแค่ชี้ให้เห็นว่าพฤติกรรมนั้นแตกต่างจากคำสั่ง watch บน Ubuntu เห็นได้ชัดว่าเวอร์ชั่นของ Ubuntu รันคำสั่งทุกสองวินาที (การขยายพารามิเตอร์ในแต่ละครั้งที่เรียกใช้) สคริปต์นี้มีพารามิเตอร์ที่ขยายก่อนที่จะถูกเรียกใช้จากนั้นเรียกใช้พารามิเตอร์เดียวกันทุกสองวินาที ดังนั้นหากคุณต้องการดูไฟล์ในไดเรกทอรีที่มีการเพิ่มไฟล์และลบสคริปต์นี้ก็ไม่ได้ช่วยอะไร มันจะมีประโยชน์เมื่อคุณไม่ได้ใช้พารามิเตอร์แบบขยาย :)
รหัสผู้บัญชาการ

@ CodeCommander ฉันคิดว่าคุณเข้าใจผิด Bash (เช่น sh) จะขยายออก*โดยไม่ผ่านไปยังคำสั่งที่คุณรัน ลองใช้: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*ในหน้าต่างเดียว ในขณะที่ทำงานคุณสามารถtouch /tmp/zz/barในหน้าต่างอื่น ดูว่า "นาฬิกา" ของคุณเห็นการเปลี่ยนแปลงหรือไม่ในหน้าต่างแรก ฉันไม่คิดว่ามันจะ มันไม่ได้สำหรับฉัน สิ่งนี้ไม่เกี่ยวกับ Ubuntu vs OSX หรือ Linux กับ Unix มันเป็นพฤติกรรมของbashตัวเอง
ghoti

1
@ghoti คุณพูดถูก ฉันเข้าใจผิด แม้ว่าจะมีคำสั่ง Linux watch คุณก็ต้องใช้เครื่องหมายคำพูด: watch "ls -l /tmp/zz/*"แต่ถ้าคุณจำไว้ว่าต้องใช้เครื่องหมายคำพูดมันก็ใช้ได้กับสคริปต์ของคุณเช่นกัน :)
รหัสผู้บัญชาการ


6

หากนาฬิกาไม่ต้องการติดตั้งผ่าน

brew install watch

มีอีกรุ่นที่คล้ายกัน / คัดลอกที่ติดตั้งและทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน

brew install visionmedia-watch

https://github.com/tj/watch



2

ฉันมีปัญหาที่คล้ายกัน

เมื่อ googled ฉันเจอลิงค์นี้เมื่อเร็ว ๆ นี้ นี่ไม่ใช่ 'การติดตั้งซอฟต์แวร์' เพียงแค่รับไบนารีสำหรับคำสั่ง 'เฝ้าดู'

และลิงก์คือรับคำสั่ง watch สำหรับ OSX


2

เพื่อป้องกันการกะพริบเมื่อคำสั่งหลักของคุณใช้เวลาในการรับรู้ให้สมบูรณ์คุณสามารถจับภาพเอาต์พุตและล้างเฉพาะหน้าจอเมื่อเสร็จสิ้น

function watch {while :; do a=$($@); clear; echo "$(date)\n\n$a"; sleep 1; done}

จากนั้นใช้งานโดย: watch istats


ควรจะecho -eแทนเพียงechoเพื่อทำให้การแบ่งบรรทัดเหล่านั้นได้อย่างถูกต้อง
Jez

1

ต่อไปนี้เป็นคำตอบในเวอร์ชันที่เปลี่ยนแปลงเล็กน้อย:

  • ตรวจสอบ args ที่ถูกต้อง
  • แสดงชื่อวันที่และระยะเวลาที่ด้านบน
  • ย้ายอาร์กิวเมนต์ "duration" เป็นอาร์กิวเมนต์ที่ 1 ดังนั้นคำสั่งที่ซับซ้อนสามารถส่งผ่านได้อย่างง่ายดายเป็นอาร์กิวเมนต์ที่เหลือ

วิธีใช้:

  • บันทึกสิ่งนี้ไปที่ ~/bin/watch
  • ดำเนินการchmod 700 ~/bin/watchในสถานีที่จะทำให้มันปฏิบัติการ
  • ลองใช้งาน watch 1 echo "hi there"

~ / bin / นาฬิกา

#!/bin/bash

function show_help()
{
  echo ""
  echo "usage: watch [sleep duration in seconds] [command]"
  echo ""
  echo "e.g. To cat a file every second, run the following"
  echo ""
  echo "     watch 1 cat /tmp/it.txt" 
  exit;
}

function show_help_if_required()
{
  if [ "$1" == "help" ]
  then
      show_help
  fi
  if [ -z "$1" ]
    then
      show_help
  fi
}

function require_numeric_value()
{
  REG_EX='^[0-9]+$'
  if ! [[ $1 =~ $REG_EX ]] ; then
    show_help
  fi
}

show_help_if_required $1
require_numeric_value $1

DURATION=$1
shift

while :; do 
  clear
  echo "Updating every $DURATION seconds. Last updated $(date)"
  bash -c "$*"
  sleep $DURATION
done

1

ลองสิ่งนี้:

#!/bin/bash
# usage: watch [-n integer] COMMAND

case $# in
    0)
        echo "Usage $0 [-n int] COMMAND"
        ;;
    *)      
        sleep=2;
        ;;
esac    

if [ "$1" == "-n" ]; then
    sleep=$2
    shift; shift
fi


while :; 
    do 
    clear; 
    echo "$(date) every ${sleep}s $@"; echo 
    $@; 
    sleep $sleep; 
done

0

ใช้ระวังจัดการแพ็กเกจ !

ติดตั้ง nix จากนั้นnix-env -iA nixpkgs.watchควรพร้อมใช้งานหลังจากทำตามคำแนะนำในการติดตั้ง (รวมถึงการจัดหา. "$HOME/.nix-profile/etc/profile.d/nix.sh"ในเชลล์ของคุณ)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.