ในสคริปต์การกำหนดค่าเชลล์ฉันจะอธิบายถึงความแตกต่างระหว่าง coreutils บน BSD ได้อย่างไรเมื่อเปรียบเทียบกับ GNU


9

จนถึงเดือนนี้การกำหนดค่าเปลือกของฉันค่อนข้างเรียบง่าย (แค่ส่วนใหญ่.bashrcหรือ.bash_profileด้วยนามแฝงบางส่วน) แต่ฉันได้ทำการปรับโครงสร้างใหม่เพื่อที่ฉันจะได้รับพฤติกรรมที่แตกต่างกันขึ้นอยู่กับว่าฉันใช้ zsh และทุบตี พวกเขาแรกมาไฟล์เปลือก config ทั่วไปที่ควรทำงานอะไรก็ตามแล้วเชี่ยวชาญสำหรับเชลล์เฉพาะที่ใช้ (ฉัน symlink นี้)

วันนี้ฉันรู้สึกประหลาดใจเมื่อlsหยุดทำงาน มันกลับกลายเป็นว่าในระหว่างการรีแฟค.bashrcเตอร์

alias ls='ls --color=always'

ที่ทำลายสิ่งต่าง ๆlsในการทุบตีใน Terminal ใน OSX เมื่อฉันเห็นว่า BSD lsชอบ-Gสี แต่ GNU (หรืออะไรก็ตามที่อยู่บน Ubuntu) ชอบ--colorมันชัดเจนว่ามีตัวเลือกไม่กี่ตัวที่แตกต่างกัน

คำถามของฉันคืออะไรวิธีที่ดีที่สุดในการพิจารณาความแตกต่างของตัวเลือกและระหว่างแกนกลาง BSD และ GNU คืออะไร? ฉันควรทดสอบตัวแปร env ในifบล็อกเพื่อดูว่ามีการใช้ระบบปฏิบัติการใดและใช้พฤติกรรมที่ถูกต้องหรือไม่ หรือมันเหมาะสมกว่าที่จะแยกไฟล์ปรับแต่งสำหรับแต่ละระบบปฏิบัติการ

ในขณะที่คำตอบสำหรับคำถามเหล่านี้อาจเป็นอัตนัยดูเหมือนว่าบทสรุปของขอบเขตของความแตกต่างระหว่าง coreutils ของ BSD และ GNU และกลยุทธ์ในการแก้ไขปัญหาเหล่านี้เพื่อให้การกำหนดค่าทั่วไปที่ใช้งานได้บน nix ส่วนใหญ่จะมีวัตถุประสงค์อย่างเป็นธรรม


เปลือกหอยเปลี่ยนจะไม่แก้ไขอะไรและแตกต่างจากls -c ls --colorแก้ไขคำถามของคุณเพื่อแก้ไข
Mikel

คำตอบ:


9

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

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

if ls --version 2>/dev/null | grep -q 'coreutils'; then
    alias ls='ls --color=always'
else
    alias ls='ls -G'
fi

ฉันเล่นกับวิธีที่แตกต่างกันและฉันคิดว่าวิธีแก้ปัญหา "น่าเกลียด" ของคุณนั้นค่อนข้างดีและไม่น่าเกลียดเลย ตามที่ปรากฏฉันไม่ได้สังเกตเห็นความไม่ตรงกันในตัวเลือกสำหรับ ls ก่อนหน้านี้เพราะฉันใช้ coreutils GNU จากพอร์ต นี่คือตัวอย่างทำไมการ 'ถ้า' บน $ OSTYPE สามารถล้มเหลวในการส่งผลลัพธ์ที่ต้องการ
เขาวงกต

มีวิธีการระงับข้อผิดพลาดที่มาจาก "if ls --version" หรือไม่เมื่อไม่มี coreutils ของ GNU (แต่ยังสามารถทดสอบ coreutils ได้)
เขาวงกต

โอ้ไม่ต้องกังวลเกี่ยวกับการระงับข้อผิดพลาด ฉันเพิ่งเปลี่ยน stderr ไปที่ / dev / null ก่อนที่จะ pip ​​เป็น grep และทำงานได้ตามที่ฉันต้องการ
เขาวงกต

3
แทนที่จะมองหาอย่างชัดเจนทำไมไม่เพียงทดสอบว่าสีงานธงเช่นcoreutils if ls --color=auto -d / >/dev/null 2>&1; then ...
Mikel

@mikel หากคุณกังวลเกี่ยวกับสีเท่านั้น (เช่นในตัวอย่าง) นั่นเป็นเรื่องปกติ หากคุณสนใจคุณสมบัติอื่น ๆ เช่นกันการตรวจสอบ coreutils นั้นมีประโยชน์
จอร์แดน

3

เกลื่อนรหัสที่มีifงบในการดำเนินการสลับกับชนิดของcoreutilsไม่ทำงาน แต่การแก้ปัญหาการเขียนโปรแกรมทำความสะอาดสำหรับการจัดการที่แตกต่างกันคือการใช้ความแตกต่าง เนื่องจากนี่คือ Bash เราไม่มี polymorphism ต่อ se แต่ฉันยุ่งกับวิธีปลอมมัน ข้อกำหนดเพียงอย่างเดียวคือ.bashrcไฟล์ของคุณฯลฯ ได้รับการจัดระเบียบเป็นฟังก์ชัน

ก่อนอื่นฉันสร้างการทดสอบสำหรับประเภทแพลตฟอร์มcoreutils :

get_coreutils_platform() {
    local ls_version="$(ls --version 2>/dev/null)"
    if [[ "$ls_version" == *"GNU coreutils"* ]]; then
        echo gnu
    else
        echo bsd
    fi
}

จากนั้นเราสามารถจัดส่งตามประเภท:

platform=$(get_coreutils_platform)
define_standard_aliases_$platform
configure_shell_vars_$platform

นี่คือการใช้BSD :

define_standard_aliases_bsd() {
    define_standard_aliases
}

configure_shell_vars_bsd() {
    configure_shell_vars
    export CLICOLOR=1
}

(โปรดทราบว่าเราใช้CLICOLORตัวแปรเพื่อเปิดสีแทนการใช้aliasซึ่งดูเหมือนว่าจะเป็นตัวทำความสะอาดน้อยกว่า)

และการแทรกซึมของGNU :

define_standard_aliases_gnu() {
    define_standard_aliases
    alias ls='ls --color=auto'
}

configure_shell_vars_gnu() {
    configure_shell_vars
}

เพื่อความสมบูรณ์ 'นี่คือตัวอย่างการใช้งานของ "ฐานนามธรรม":

define_standard_aliases() {
    alias ll='ls -l'
    alias l.='ls -d .*'
}

configure_shell_vars() {
    export EDITOR=vim
}

สิ่งนี้สะอาดกว่าเว้นแต่คุณใช้ระบบ 0.1% เช่น GNU ls แต่ไม่ใช่ GNU cat ที่ติดตั้ง (อาจจะเก่าและมี fileutils แต่ไม่ใช่ textutils) ฉันถูกล่อลวงไปใช้lsในการมอบหมายงานของคุณมากกว่าโดยเฉพาะอย่างยิ่งเนื่องจากไม่มีนามแฝงของคุณเกี่ยวข้องกับcat cat
Mikel

นอกจากนี้คุณไม่ควรต้องในนามแฝงที่สองและสามของคุณเนื่องจากนามแฝงแรกเพิ่มตัวเลือกที่จะ--color=auto ls
Mikel

1
@ Mikel โอ้โหฉันไม่ได้ตระหนักเลยว่าaliasมันเกิดขึ้นซ้ำแล้วซ้ำอีก นั่นทำให้ฉันทำตัวอย่างง่ายขึ้นมาก
Michael Kropat

ดีกว่ามาก :-)
Mikel

0

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

http://www.pixelbeat.org/scripts/l

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