คำสั่งประวัติภายในสคริปต์ทุบตี


20

ประวัติเป็นคำสั่งในตัวเชลล์ฉันไม่สามารถใช้สิ่งนั้นได้ในสคริปต์ BASH ดังนั้นมีวิธีการนี้โดยใช้สคริปต์ทุบตี?
ที่นี่เราไปสคริปต์ของฉันสำหรับคุณ:

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

คำตอบ:


31

Bash จะปิดใช้งานประวัติในเชลล์แบบไม่มีการโต้ตอบตามค่าเริ่มต้น แต่คุณสามารถเปิดใช้งานได้

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

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

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


สิ่งนี้ปฏิเสธที่จะทำงานในสคริปต์:histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@KenSharp นั่นเป็นเพราะคุณพยายามที่จะใช้มันในสคริปต์ sh (และคุณshเป็นผู้ตัดสินโดยใช้ถ้อยคำที่แน่นอนของข้อความแสดงข้อผิดพลาด) ในการเข้าถึงประวัติของ bash คุณต้องใช้ bash (สคริปต์ที่ขึ้นต้นด้วย#!/bin/bashหรือ#!/usr/bin/env bash)
Gilles 'หยุดความชั่วร้าย'

1
@KenSharp ใช่มันเป็น คุณเห็นได้ชัดว่าคุณวิ่งมันภายใต้ประให้ข้อความข้อผิดพลาด Bash ไม่มีข้อความแสดงข้อผิดพลาดIllegal option(จะบอกว่าset: history: invalid option name)
Gilles 'ดังนั้นหยุดความชั่วร้าย'

ปัญหานี้ก็คือว่ามันเพิ่มคำสั่งต่อไปนี้ทั้งหมดset -o history กับประวัติศาสตร์ซึ่งจากนั้นจะถูกยัดไส้กับรายการเช่นif [... vars=$(...ฯลฯ
ภูมิพลอดุลยเดช

1
@nath นั่นคือคำถามที่ถาม มันไร้จุดหมายสวยมากอย่างที่ฉันชี้ให้เห็น การตรวจสอบกิจกรรมเป็นปัญหาที่ยากที่ประวัติเชลล์ไม่สามารถแก้ไขได้ หากคุณกำลังดีบักสคริปต์ก็set -xมีประโยชน์มากกว่า
Gilles 'หยุดความชั่วร้าย'

6

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

ทำไมไม่ไปโดยตรงไปยังแหล่งที่มา${HOME}/.bash_historyแทนที่ด้วยhistory | tail -100 tail -100 ${HOME}/.bash_history(ถ้าคุณใช้การประทับเวลาคุณอาจต้องทำอะไรสักอย่างตามแนวของgrep -v ^# ${HOME}/.bash_history | tail -100)


ที่จริงแล้วด้วยการประทับเวลาคุณควรจริงgreq -v '^#[0-9]\+$'(บางครั้งฉัน "รัน" ความคิดเห็นในเปลือกของฉัน ... )
PlasmaBinturong

และที่จริงแล้วในกรณีของฉันฉันต้องใช้หมายเลขบรรทัดประวัติที่ถูกต้องแต่มีความแตกต่างระหว่างผลลัพธ์ของhistoryและgrepวิธีการ ...
PlasmaBinturong

history -a; history -c; history -rตกลงแก้ไขคือการประสานรายการประวัติกับแฟ้มประวัติเช่นนี้ (เพิ่มชัดเจนอ่าน)
PlasmaBinturong

2

หากคุณต้องการใช้เอาต์พุตของhistoryคำสั่งจากเซสชันเชลล์ที่แอ็คทีฟในสคริปต์คุณสามารถใช้นามแฝงเพื่อรันคำสั่งก่อน จากนั้นในนามแฝงเดียวกันคุณสามารถเรียกส่วนที่เหลือของสคริปต์ ด้วยการกำหนดค่าดังกล่าวคุณสามารถบรรลุผลลัพธ์เป็นหลักเหมือนกับการมีhistoryคำสั่งในสคริปต์จริง

ตัวอย่างเช่นคุณสามารถสร้างนามแฝงเช่นนี้โดยสมมติว่าชื่อของสคริปต์คือ script.sh:

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

และเปลี่ยนสคริปต์เป็น:

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

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

การอัปเดตไฟล์ประวัติสะสมของฉันนั้นยุ่งยากน้อยกว่ามากโดยไม่ต้องเข้าสู่เชลล์ใหม่ให้มี ~/bash_historyอัปเดต สำหรับการตรวจสอบเซิร์ฟเวอร์จะเห็นได้ชัดว่าไม่ได้ผลดังที่กล่าวไว้ในคำตอบอื่น ๆ

การใช้งานของฉันโดยเฉพาะคือ:

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

สคริปต์hby.shจะดึงรายการที่ไม่ซ้ำกันทั้งหมดจาก~/.bash_history*ไฟล์ทั้งหมด



1

สร้างสคริปต์ชื่อscript.shด้านล่าง มันสร้างสคริปต์ชื่อ X และใส่ Y จำนวนบรรทัดในประวัติของคุณ

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

จากนั้นถ้าคุณต้องการสร้างสคริปต์เพื่อให้งานที่มีชื่อว่า "งาน" สำเร็จซึ่งคุณได้ทำมาแล้วสำหรับการทำงาน 14 บรรทัดล่าสุด

script.sh task 14

จากนั้นล้างประวัติของคุณเพื่อสร้างสคริปต์ที่ดี!


histtest.sh: 5: set: Illegal option -o history
เคนชาร์ป

1

คำสั่ง history ถูกปิดใช้งานโดยค่าเริ่มต้นในสคริปต์ทุบตีนั่นคือสาเหตุที่แม้แต่คำสั่ง history จะไม่ทำงานในไฟล์. sh สำหรับการเปลี่ยนเส้นทางโปรดเปลี่ยนไฟล์ bash_history ภายในไฟล์. sh

หรือกลไกประวัติสามารถเปิดใช้งานได้โดยการกล่าวถึงไฟล์ประวัติและเปลี่ยนพารามิเตอร์รันไทม์ตามที่กล่าวถึงด้านล่าง

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

หมายเหตุ: ดังกล่าวข้างต้นสองบรรทัดที่ด้านบนของไฟล์สคริปต์ ตอนนี้คำสั่งประวัติศาสตร์จะทำงานในประวัติศาสตร์


0

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


-1

คำตอบสั้น ๆ :

ใช้history -pเพื่อขยายประวัติอย่างชัดเจน

ตัวอย่างดังต่อไปนี้

กรณีใช้หนึ่งเกิดขึ้นมากสำหรับฉันคือ:

  • คำสั่งก่อนหน้าได้รับรายชื่อไฟล์และพิมพ์ไปยัง stdout
  • ฉันต้องการแก้ไขไฟล์เหล่านั้นด้วย vim

ตั้งแต่ทุบตีของฉันset -o histexpandมักจะเป็นสิ่งที่ฉันพิมพ์

vim $(!!)

เพื่อแก้ไขไฟล์เหล่านั้นที่ระบุโดยคำสั่งก่อนหน้า

บางครั้งน่าเศร้าที่เกิดข้อผิดพลาดดังนั้นฉันจึงเปิดใช้งานการตรวจสอบโดย shopt -s histverifyน่าเศร้าที่บางครั้งความผิดพลาดที่เกิดขึ้นดังนั้นผมจึงเปิดใช้งานการตรวจสอบโดย

ตอนนี้ฉันสามารถตรวจสอบการขยายตัวได้ด้วยค่าใช้จ่ายเพิ่มเติมหนึ่งรายการ Returnคีย์คีย์

วันนี้ฉันต้องการที่จะห่อรายละเอียดเหล่านั้นไว้ในฟังก์ชั่นทุบตีเนื่องจากฉันใช้พวกเขามาก

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

ที่นี่ฉันใช้สองซ้อนกันcommand substitutionหนึ่งภายในเพื่อขยาย!!ไปยังคำสั่งก่อนหน้าหนึ่งนอกเพื่อดำเนินการและรับเอาท์พุท

ตอนนี้ฉันสามารถบรรลุผลเดียวกันโดยมีเพียงสามปุ่มเท่านั้นและหนึ่งในนั้นคือReturn!

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