ใช้การเปลี่ยนเส้นทางเอาต์พุตโดยไม่ได้ตั้งใจ> แทนที่จะไปป์ |


21

เดือนที่แล้วฉันเขียนสคริปต์ Python เพื่อจับคู่ MAC และที่อยู่ IP จาก stdin และเมื่อสองวันก่อนฉันจำได้และเคยกรองเอาท์พุทของtcpdumpแต่มันผิดไปเพราะการพิมพ์ผิด ฉันพิมพ์

tcpdump -ne > ./mac_ip.py

และผลลัพธ์คืออะไร แต่ผลลัพธ์ควรเป็น "ไม่ทราบ" หากไม่สามารถแยกวิเคราะห์อินพุตดังนั้นฉันได้cat ./mac_ip.pyและพบข้อมูลทั้งหมดtcpdumpแทนที่จะเป็นโปรแกรม จากนั้นฉันก็ตระหนักว่าฉันควรใช้

tcpdump -ne | ./mac_ip.py

มีวิธีใดบ้างที่จะนำโปรแกรมของฉันกลับคืนมา อย่างไรก็ตามฉันสามารถเขียนโปรแกรมของฉันอีกครั้ง แต่ถ้ามันเกิดขึ้นอีกครั้งด้วยโปรแกรมที่สำคัญกว่าฉันควรจะทำอะไรบางอย่าง หรือมีวิธีใดที่จะบอกการเปลี่ยนเส้นทางเอาต์พุตเพื่อตรวจสอบไฟล์และเตือนว่าไฟล์นั้นรันได้หรือไม่?


18
คุณสามารถทำให้โปรแกรมของคุณกลับมาจากการสำรองข้อมูลครั้งล่าสุดก่อนที่จะเขียนทับได้ BTW ในเปลือกคุณสามารถระบุset -o noglobberและทุบตีจะไม่เปลี่ยนเส้นทางไปยังไฟล์ที่มีอยู่อีกต่อไป ดูที่นี่สำหรับรายละเอียด: cyberciti.biz/tips/howto-keep-file-safe-from-overwriting.html
Eckes

12
คุณไม่ควรได้รับอนุญาตเป็นลายลักษณ์อักษรจากผู้ปฏิบัติการที่สำคัญ ...
Hagen von Eitzen

20
@eckesset -o noclobber
GnP

38
@HagenvonEitzen ฉันเกลียดคำแนะนำเช่นนั้นราวกับว่าคุณได้ตั้งค่าความเป็นเจ้าของและการอนุญาตที่เหมาะสมสำหรับเชลล์แบบใช้ครั้งเดียวและสคริปต์หลามที่คุณเคยเขียนก่อนใช้งาน (และแน่นอนกลับมาอีกครั้งสั้น ๆ หากคุณต้องแก้ไขมัน ) มันมีความหมายมากกว่าเพียงเล็กน้อย "คุณไม่ควรพิมพ์>เมื่อคุณหมายถึง|" อย่าลืมความจริง
Jason C

30
repit Git มีราคาถูก มอบรหัสทั้งหมดของคุณไม่ว่าเล็กและไร้ความหมายแล้วความผิดพลาดเช่นนี้เป็นการแก้ไขที่ง่ายและรวดเร็ว
casey

คำตอบ:


22

น่าเศร้าที่ฉันสงสัยว่าคุณจะต้องเขียนใหม่ (หากคุณมีการสำรองข้อมูลนี่เป็นเวลาที่จะนำออกมาหากไม่ฉันขอแนะนำอย่างยิ่งให้คุณตั้งค่าระบอบการสำรองข้อมูลสำหรับอนาคตตัวเลือกมากมายพร้อมใช้งาน แต่ปิดหัวข้อสำหรับคำตอบนี้)

ผมพบว่าการวาง executables ในไดเรกทอรีที่แยกต่างหากและการเพิ่มไดเรกทอรีที่ไปPATHเป็นประโยชน์ วิธีนี้ฉันไม่จำเป็นต้องอ้างอิงไฟล์ที่เรียกใช้งานโดยพา ธ ที่ชัดเจน ฉันแนะนำไดเรกทอรีโปรแกรมสำหรับบุคคลสคริปต์ (ส่วนตัว) เป็นและมันสามารถเพิ่มเส้นทางการค้นหาโปรแกรมที่มี"$HOME"/bin PATH="$HOME/bin:$PATH"ซึ่งโดยปกติจะถูกเพิ่มลงในสคริปต์เริ่มต้นเปลือกและ.bash_profile / หรือ.bashrc

สุดท้ายไม่มีอะไรหยุดคุณลบสิทธิ์การเขียนสำหรับตัวคุณเองในทุกโปรแกรมปฏิบัติการ

touch some_executable.py
chmod a+x,a-w some_executable.py    # chmod 555, if you prefer

ls -l some_executable.py
-r-xr-xr-x+ 1 roaima roaima 0 Jun 25 18:33 some_executable.py

echo "The hunting of the Snark" > ./some_executable.py
-bash: ./some_executable.py: Permission denied

2
/usr/local/binเป็นตำแหน่งมาตรฐานสำหรับไฟล์เรียกทำงานและสคริปต์ที่ผู้ใช้สร้างขึ้น
gardenhead

4
@gardenhead ขึ้นอยู่กับการตั้งค่าระบบ /usr/localมีไว้สำหรับสิ่งที่เฉพาะโฮสต์ (เมื่อเทียบกับไดเรกทอรีที่ใช้ร่วมกันข้ามโฮสต์ผ่านเครือข่าย) และอาจหรือไม่อาจเขียนได้โดยผู้ใช้ที่ไม่ใช่รูท
chepner

4
@gardenhead เป็นที่ตั้งมาตรฐานอย่างแน่นอน ฉันใช้/use/local/binสำหรับสคริปต์และโปรแกรมที่ติดตั้งในเครื่องซึ่งมีแนวโน้มที่จะถูกใช้โดยบัญชีผู้ใช้หลายบัญชีและ$HOME/binเป็นเรื่องส่วนตัวสำหรับผู้ใช้คนเดียว มีคุณค่าทั้งคู่
roaima

1
โปรดทราบว่าดูเหมือนว่า Fedora กำลังพยายามที่จะผลักดันการใช้งาน$HOME/.local/bin
Zan Lynx

1
@Zan eeeww! อย่างจริงจังว่าขอบคุณ ดูเหมือนว่า RH กำลังพยายามที่จะผลักดันทุกอย่างให้~/.localเป็นเพราะมันเป็นรายการอื่นย้ายจากสถานที่ "ดั้งเดิม" ของมัน
roaima

38

เพื่อป้องกันไม่ให้ไฟล์ที่มีอยู่จากการเขียนทับโดยการเปลี่ยนเส้นทาง>การใช้งานnoclobberตัวเลือกในbashหรือ POSIX เหมือนเปลือก (ยังอยู่ใน(t)cshที่คุณลักษณะนี้มาจริง แต่คุณทำset noclobberแทนset -o noclobber/ set -Cมี) จากนั้นหากคุณต้องการบังคับให้แทนที่ไฟล์ให้ใช้ตัว>|ดำเนินการเปลี่ยนเส้นทาง ( >!ใน(t)csh)

ตัวอย่าง:

$ echo abc > file
$ set -o noclobber
$ echo xyz > file
bash: file: cannot overwrite existing file
$ echo xyz >| file
$ cat file
xyz

BTW คุณสามารถตรวจสอบการตั้งค่าปัจจุบันด้วยset -o:

$ set -o
...
monitor         on
noclobber       on
noexec          off
...

ในขณะที่สิ่งนี้ตอบคำถามได้อย่างสมบูรณ์แบบฉันไม่อยากจะแนะนำ 1. พิมพ์ดีด>|แทนไม่มากน่าจะน้อยกว่าการพิมพ์| >2. เป็นเรื่องง่ายและขอแนะนำให้ทำการสำรองข้อมูล (ตัวแก้ไขที่คุ้มค่าชื่อสามารถบันทึกรุ่นล่าสุดได้มีcronฯลฯ ) 3. โค้ดทุกชิ้นควรอยู่ภายใต้การควบคุมเวอร์ชันแม้แต่สคริปต์เล็ก ๆ YMMV
maaartinus

2
@maaartinus เกิดขึ้น 1) การพิมพ์อักขระสองตัวที่แยกจากกันแทนที่จะเป็นตัวเดียวนั้นมีโอกาสน้อยกว่ามาก 2) การสำรองข้อมูลอย่างชัดเจนเป็นสิ่งจำเป็นไม่มีใครแนะนำ OP ให้ทำการสำรองข้อมูลคำตอบนี้ไม่แนะนำให้ไม่มีการสำรองข้อมูลและการสำรองข้อมูลเอดิเตอร์ถือว่าคุณได้แก้ไขไฟล์ในโปรแกรมแก้ไขแล้ว 3) อีกครั้งคุณแค่คิดถึงรหัสที่ OP ได้เขียนไว้เช่นเดียวกับตัวอย่างนี้ แต่คำถามและคำตอบนี้ใช้ได้กับไฟล์ใด ๆบนเครื่องรวมถึงระบบปฏิบัติการ
terdon

8

ฉันขอแนะนำอย่างยิ่งให้มีสคริปต์ที่สำคัญภายใต้repo คอมไพล์ซิงค์จากระยะไกล ( แพลตฟอร์มที่โฮสต์ด้วยตนเองที่น่าสนใจจะทำ) ดังที่ @ casey แสดงความคิดเห็น

วิธีนี้คุณจะได้รับการปกป้องจากความผิดพลาดของมนุษย์ที่ไม่ดีเช่นการคืนค่าไฟล์กลับสู่สถานะการทำงานก่อนหน้าและดำเนินการอีกครั้ง


4

สามารถกู้คืนไฟล์ได้หรือไม่

คำตอบสั้น ๆ : ไม่ปกติ

@ Mark Plotnick ชี้ให้เห็นในความคิดเห็นที่คุณสามารถกู้คืน.pyไฟล์จาก.pycการใช้Uncompyle นี่ควรจะสมบูรณ์แบบสำหรับสถานการณ์ของคุณ

โดยทั่วไปแล้วมันยากกว่านี้มาก ในทางทฤษฎีคุณสามารถใช้เครื่องมือทางนิติเวชในการยกเลิกการลบไฟล์ อาจเป็นวิธีที่ง่ายที่สุดที่ฉันเคยใช้คือtestdisk("PhotoRec") บางครั้งใช้งานได้และเป็นกระบวนการที่ช้า มันมักจะไม่คุ้มค่าดังนั้นใช่มันเป็นไปได้แต่คำตอบที่แท้จริงคือ "ไม่"

สามารถ>จะมีการเปลี่ยนแปลงที่จะไม่เขียนทับ executables?

ไม่ไม่มีวิธีมาตรฐานในการบอกให้เชลล์ไม่เปลี่ยนเส้นทางเฉพาะไฟล์ที่ทำเครื่องหมายได้เท่านั้น มี "noclobber" ซึ่งจะป้องกันการเปลี่ยนเส้นทางไปยังไฟล์ที่มีอยู่ปฏิบัติการหรือไม่ แต่เห็นความคิดเห็นของฉันที่ด้านล่าง

จะทำอะไรในอนาคต

  1. นี่อาจฟังดูงี่เง่า แต่เพื่อป้องกันข้อผิดพลาดในอนาคตคุณอาจไม่จำเป็นต้องทำอะไรเลย เดิมพันของฉันคือการที่คุณได้เรียนรู้บทเรียนนี้แล้ว

    ฉันใช้และสอนยูนิกซ์มาเป็นเวลานานและในขณะที่ผู้คนมักทำผิดพลาดครั้งเดียวพวกเขาไม่ค่อยพูดซ้ำ ทำไมไม่ ด้วยเหตุผลเดียวกับที่คนมีดมีดไม่ได้ตัดตัวเอง: มนุษย์เรียนรู้ได้ดี ในที่สุดการทำสิ่งที่ถูกต้องจะกลายเป็นธรรมชาติที่สอง

  2. ใช้เท็กซ์เอดิเตอร์ที่สร้างการสำรองข้อมูลสำหรับคุณ ตัวอย่างเช่นหากคุณใช้emacsโปรแกรมรุ่นก่อนหน้าของคุณจะถูกบันทึกไว้ใน mac_ip.py ~ โปรแกรมแก้ไขอื่น ๆ สามารถกำหนดค่าให้ทำงานในทำนองเดียวกัน (เช่น "set backup" ใน.nanorc) สำหรับบรรณาธิการที่ไม่รองรับการสำรองข้อมูลอัตโนมัติคุณสามารถสร้างฟังก์ชั่นง่าย ๆ ใน. bashrc ของคุณ:

    myeditor() { cp -p "$1" "$1~";  editor "$1"; }
    
  3. ทำให้การทำสำเนาเป็นเรื่องง่าย ตัวอย่างเช่นในไดเรกทอรีของโครงการที่คุณกำลังดำเนินการอยู่คุณอาจมี Makefile ที่มีเป้าหมายดังนี้:

    # Use `make tar` to backup all files in this directory.
    # Tar filename will be ../<currentdirectory>-<date>.tar.gz 
    DIRNAME = $(shell basename `pwd`)
    TIMESTAMP = $(shell date +%s)
    tar:
        @echo "[Tarring up ${DIRNAME}.tar.gz]"
        (cd .. ; tar -zcvf "${DIRNAME}-${TIMESTAMP}.tar.gz" "${DIRNAME}")
    

    (หมายเหตุ: stackexchange กำลังทำการแท็บ TAB ด้านบนเป็น 4 ช่องว่าง)

  4. ในทำนองเดียวกันคุณสามารถสร้างเป้าหมาย Makefile ที่ทำrsyncกับโฮสต์ Unix ระยะไกลที่คุณsshสามารถเข้าถึงได้ (ใช้ssh-copy-idดังนั้นคุณจะไม่ถูกถามรหัสผ่านซ้ำ)

  5. gitใช้ มีแบบฝึกหัดที่ยอดเยี่ยมมากมายในการเริ่มต้น ลองman gittutorial, และman gittutorial-2 man giteverydayการตั้งค่าที่เก็บ git ของคุณเองนั้นไม่ยาก แต่คุณสามารถสร้างที่เก็บระยะไกลได้โดยไม่เสียค่าใช้จ่ายที่ github.com

  6. หากการแก้ปัญหาดังกล่าวข้างต้นมีน้ำหนักมากเกินไปคุณสามารถบันทึกสคริปต์ขนาดเล็กเพื่อgist.github.com แม้ว่าจะเป็นไปได้ที่จะวางหรืออัปโหลดจากเว็บเบราว์เซอร์ฉันขอแนะนำให้ใช้อินเทอร์เฟซส่วนสำคัญบรรทัดคำสั่งเพื่อทำให้สิ่งต่าง ๆ เป็นเรื่องง่าย

ฉันไม่แนะนำให้ใช้ "noclobber" อย่างยิ่ง

ใช่ถ้าคุณเลือกคุณสามารถทำได้set -o noclobberดังนั้นคุณจะได้รับข้อความแสดงข้อผิดพลาดทุกครั้งที่คุณพยายามเขียนทับไฟล์ที่มีอยู่ นี่เป็นความคิดที่ไม่ดีในความคิดของฉัน * * * *

ทำให้เชลล์ทำงานในลักษณะที่ไม่ได้มาตรฐานโดยไม่มีข้อบ่งชี้ที่มองเห็นได้ว่าเปิดใช้งานอยู่หรือไม่ คุณต้องใช้ไวยากรณ์ที่แตกต่างกันสำหรับการทำสิ่งปกติ ที่เลวร้ายที่สุดถ้าคุณชินกับ noclobber ดังนั้นสักวันคุณจะใช้เครื่อง Unix อีกเครื่องโดยไม่ใช้ noclobber และอุบัติเหตุประเภทนี้อาจเกิดขึ้นอีกครั้ง

อย่างที่คุณอาจจะรู้ว่า Unix shell นั้นถูกออกแบบมาให้เป็นเครื่องมือที่คมชัดสำหรับผู้เชี่ยวชาญ มันใช้งานได้เร็วและจะไม่ไปขวางทางคุณ - และมันจะตัดคุณถ้าคุณลืมว่าปลายด้านใด แต่ยิ่งคุณใช้มันมากเท่าไหร่ฉันก็ยิ่งคิดว่ามันจะเป็นเรื่องดี


*เชิงอรรถ: อาจใช้ความคิดเห็นของฉันกับเกลือเม็ด ฉันยังเป็นคนประเภทที่คิดว่าล้อฝึกซ้อมจักรยานเป็นความคิดที่ไม่ดี


ฉันยังสอนยูนิกซ์อยู่พักหนึ่ง นักเรียนของฉันหลายคนไม่เคยเรียนรู้ที่จะชื่นชมความเรียบง่ายโดยตรงของ Unix ฉันบอกพวกเขาว่าพวกเขาไม่ได้อยู่คนเดียวและอย่างน้อยก็ยังสามารถเรียนรู้ได้ในขณะที่มอบความไว้วางใจในคู่มือของ Unix Hater ซึ่งทำแผนที่บางส่วนของทุ่นระเบิดสำหรับพวกเขา simson.net/ref/ugh.pdf
Jason

อีกทั้งฉันเห็นด้วย - การฝึกล้อบนจักรยานมีประโยชน์สำหรับทุกคนที่เรียนรู้วิธีขี่สามล้อ
Jason

2

คุณอาจกู้คืนข้อมูลได้หลังจากที่เกิดขึ้นครั้งแรกหากคุณเพิ่งดูหรือแก้ไขสคริปต์และยังคงอยู่ในบัฟเฟอร์หน่วยความจำ มิฉะนั้นคุณจะโชคไม่ดีนัก

หากคุณไปที่teeเพื่อเขียนไปยังไฟล์ (รวมถึงSTDOUT) แทน>(หรือtee -aแทน>>) จากนั้นคุณสามารถแทนที่teeด้วยนามแฝงฟังก์ชั่นหรือ symlink ไปยังสคริปต์ที่เตือนผู้ใช้หากไฟล์ที่พวกเขากำลังจะเขียน เพื่อเป็นปฏิบัติการ

ต่อไปนี้คือไม่เหมาะและสามารถปรับปรุงได้มากแต่มันเป็นจุดเริ่มต้นเพียงเป็นตัวอย่างของวิธีนี้เป็นไปได้:

wee.sh:

#!/bin/bash

if [ -n "${2}" ]; then
  if [ "$(ls -l "${2}" | awk '{print $1}' | grep x)" ]; then
    echo executable
  else
    tee -a "${2}"
  fi
elif [ "$(ls -l "${1}" | awk '{print $1}' | grep x)" ]; then
  echo executable
else
  tee "${1}"
fi

... งั้นecho 'alias tee="/path/to/wee.sh"' >> ~/.bashrcหรืออะไรที่คล้ายกัน

อย่างน้อยคุณจะได้รับการฝึกฝนมากขึ้นและสคริปต์ Python รุ่นที่สองของคุณอาจจะดีกว่าครั้งแรกมาก!


1

คุณไม่ได้ระบุว่าคุณกำลังทำงานบนพีซีหรือเซิร์ฟเวอร์ หากไฟล์ของคุณถูกจัดเก็บไว้ในเซิร์ฟเวอร์ไฟล์โดยเฉพาะมักจะมีการสำรองข้อมูลอัตโนมัติ ("สแน็ปช็อต") ที่ถูกเก็บไว้โดย (OS บน) ฮาร์ดแวร์ไฟล์เซิร์ฟเวอร์

ภายใต้ Linux

ไดเร็กทอรีสแน็ปช็อตเสมือนที่ซ่อนอยู่มีอยู่ในทุกไดเร็กทอรีในระบบไฟล์ของคุณ

ลอง:

cd .snapshot   
ls -l

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

hourly.0
hourly.1
hourly.2
hourly.3
hourly.4
hourly.5
nightly.0
nightly.1
nightly.2
nightly.3
nightly.4
nightly.5
nightly.6
weekly.0
weekly.1
weekly.2

ไปที่ไดเรกทอรี timepoint ใด ๆ ที่เก่าพอ (ก่อนที่จะเขียนทับไฟล์ผิดพลาด) ภายในไดเรกทอรี timepoint คุณควรเห็นสถานะของ../..ไดเรกทอรี (และไดเรกทอรีย่อยทั้งหมด) ณ จุดนั้นในอดีต

cd nightly.6
ls  # look around   
tee < mac_ip.py  # check for the correct content
cp mac_ip.py ~/safekeeping/mac_ip.py  # save the old file

หมายเหตุ:

  1. ls -aจะไม่แสดง.snapshotไดเรกทอรี คุณต้องตั้งชื่อให้ชัดเจน มันถูกแทรกโดยเซิร์ฟเวอร์ไฟล์จริง ไม่มีอยู่ในไดเร็กทอรีจริงในระบบไฟล์ของคุณ
  2. ภาพรวมอัตโนมัติเหล่านี้เป็นประวัติย้อนกลับ ในที่สุดการเปลี่ยนแปลงเก่า ๆ ก็จะล้มไปในที่สุดและก็สูญเสียไป คุณต้องใช้เทคนิคนี้โดยเร็วที่สุดหลังจากคุณทราบว่าคุณต้องการไฟล์กลับ

ภายใต้ Windows

ไดเรกทอรีสแนปชอตที่ซ่อนอยู่อาจมีชื่อว่า ~ snapshot และมีอยู่ที่ระดับรากของไดรฟ์ที่กำหนด

คำแนะนำ

ภาพรวมเป็นเครือข่ายความปลอดภัยที่ทำงานเกือบทุกเวลา แต่ไม่ใช่ทุกครั้ง ฉันเห็นด้วยกับคำแนะนำอื่น ๆ ที่จะใช้ระบบควบคุมเวอร์ชัน (เช่นgit) แม้กระทั่งไฟล์ที่ไม่สำคัญ


1

มันเคยถูกกล่าวมาก่อนแล้วและฉันจะพูดอีกครั้ง ใช้ระบบควบคุมการแก้ไข

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

ตัวอย่างของเครื่องมือควบคุมการแก้ไข ได้แก่ การโค่นล้ม (SVN) (เก่าไปหน่อยตอนนี้ แต่ยังดีอยู่), mercurial (hg) และ git (git) (ยากที่จะใช้) svn นั้นดีสำหรับเอกสารออฟฟิศและอื่น ๆ ที่สามารถผสานกันได้ git และ hg นั้นเหนือกว่าสำหรับบทบาทอื่น ๆ ส่วนใหญ่ hg และ git อนุญาตให้คุณทำงานแบบออฟไลน์และซิงโครไนซ์กับเซิร์ฟเวอร์ระยะไกลสำหรับการแจกจ่ายและสำรองข้อมูล

อ่านข้อมูลเกี่ยวกับการควบคุมการแก้ไขจากนั้นแจกจ่ายการควบคุมการแก้ไขแล้วลองใช้


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