คำสั่ง 'dot space filename' กำลังทำอะไรในการทุบตี?


30

เมื่อใช้ bash shell บางครั้งฉันเก็บตัวแปรสภาพแวดล้อมไว้ในไฟล์ข้อความที่ฉันคัดลอก / วางเนื้อหาของเช่น export.txt:

export FOO=bar
export FIZZ=buzz

มีคนแสดงฉันแทนการคัดลอก / วางฉันสามารถพิมพ์ในเทอร์มินัล

. exports.txt

ซึ่งจะมีผลเช่นเดียวกับการคัดลอก / วาง

กลไกในการใช้คำสั่ง 'ชื่อไฟล์ dot space' คืออะไร มันยากที่จะนึกถึงคำค้นหา

ฉันต้องการที่จะเข้าใจว่าเกิดอะไรขึ้นและรายละเอียดทั่วไปของสิ่งที่ซับไลน์นี้กำลังทำอยู่


23
เรียกใช้help . สิ่งนี้สั้นเกินไปเอ็นจิ้น Stack Exchange คิดว่าสั้นเกินไปที่จะแสดงความคิดเห็น
Wildcard

5
ฉันสงสัยว่าทำไมคำถามเหล่านี้เกิดขึ้นในเว็บไซต์นี้ด้วย พวกเขาได้รับการตอบหลายครั้งในกองมากเกิน , Ask อูบุนตูและUnix และ Linux
fedorqui

หากต้องการเรียกใช้ dot-space คุณจะต้องพิมพ์'. ' argsด้วยเครื่องหมายคำพูดเดี่ยวหรือคู่ มิเช่นนั้นช่องว่างที่ไม่อยู่ในเครื่องหมายคำพูดจะถูกกินโดยการทุบตีเมื่อวิเคราะห์คำลงในโทเค็น (ดูที่ "การแยกคำ" ในคู่มือทุบตี)
Peter Cordes

1
ในทุบตีชื่อสำรองสำหรับ.คือsourceซึ่งหมายถึง "คำสั่งต้นฉบับจากไฟล์นี้" อย่างน้อยสำหรับฉัน
jpaugh

1
คำถามที่พบบ่อยเกี่ยวกับUnix & Linuxคือunix.stackexchange.com/questions/58514 (และunix.stackexchange.com/questions/17815และunix.stackexchange.com/questions/43882และunix.stackexchange.com/questions/312573และunix.stackexchange.com/questions/308109และ ... )
JdeBP

คำตอบ:


40

.( "จุด") คำสั่งเป็นคำพ้อง / ทางลัดสำหรับเปลือกในตัวsourceคำสั่ง

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


49
ที่จริงแล้วsourceเป็นคำพ้อง / ทางลัดที่ไม่ได้มาตรฐานและไม่พกพาได้สำหรับคำสั่ง"dot" ( ) ที่กำหนดโดย POSIX.ไม่ใช่วิธีอื่น
terdon

8
ทุบตียังมีที่ไม่ได้มาตรฐานsourceและไม่ได้มาตรฐาน.ในโหมดที่ไม่ใช่ POSIX $PATHซึ่งทั้งสองค้นหาไดเรกทอรีปัจจุบันถึงแม้ว่ามันจะไม่ได้เป็นส่วนหนึ่งของ ในโหมด POSIX ก็มีมาตรฐานที่ไม่ได้ค้นหาไดเรกทอรีปัจจุบันและไม่มี. sourceในโหมดใดไม่มีsourceความหมายเหมือนกันกับ.คำสั่งของ POSIX
hvd

26

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

ว่าฉันมีไฟล์ที่script.shมีเนื้อหาต่อไปนี้:

cd dir

หากฉันจะเรียกใช้สคริปต์นี้ตามปกติ ( sh script.sh) ฉันจะเห็นสิ่งนี้:

olle@OMK2-SERVER:~$ sh script.sh
olle@OMK2-SERVER:~$

แต่ถ้าฉันจะแหล่งสคริปต์ ( . script.sh) ฉันจะจบลงด้วยสิ่งนี้:

olle@OMK2-SERVER:~$ . script.sh
olle@OMK2-SERVER:~/dir$

สังเกตว่าในกรณีที่สองไดเรกทอรีทำงานของเชลล์หลักของเรานั้นเปลี่ยนไป!

นี้เป็นเพราะ (ตามที่ออกมาชี้ในคำตอบอื่น ๆ ) ตัวอย่างแรกวิ่งใน subshell ของตัวเอง (คนshขั้นตอนที่เราเริ่มต้นด้วยshคำสั่งนี้จะได้รับการพื้นเปลือกใด ๆbash, dashคุณชื่อมัน) มันเปลี่ยนแปลง directory ที่นั่น ไม่ทำอะไรและปิดตัวลง ในขณะที่ตัวอย่างที่สองทำงานในเชลล์หลักของเราและดังนั้นจึงเปลี่ยนไดเรกทอรีที่นั่น!


4

นี่คือตัวอย่าง

ไฟล์สคริปต์: mytest.sh

cat mytest.sh

#!/bin/bash

myvar=1
mystring="Hello World"

หากคุณพยายามพิมพ์ตัวแปรใด ๆ ข้างต้นคุณจะไม่ได้อะไรเลย

echo $myvar

แต่ถ้าคุณทำ

. mytest.sh

หรือ

source mytest.sh

แล้ว

echo $myvar

มันจะพิมพ์ 1

เป็นเพียงคำตอบแบบเห็นภาพของสิ่งที่ Spiff เขียน


ดังนั้นการตีความตัวอย่างของคุณการใช้exportก็ต่อเมื่อต้องใช้ตัวแปรเหล่านั้นใน subshells ฉันสามารถละเว้นexportในไฟล์ได้หากตัวแปรนั้นมีไว้เพื่อใช้ในเชลล์ปัจจุบันเท่านั้น นั่นถูกต้องใช่ไหม?
iancoleman

1
ค่อนข้างถูกต้องและฉันก็บอกว่าใช่ อย่างไรก็ตามการใช้คำสั่งส่งออกมีประโยชน์มากขึ้นหรือเข้าใจได้ง่ายขึ้นถ้าคุณคิดถึงตัวแปรสภาพแวดล้อมของเชลล์ ตัวอย่างเช่น $ HOME หรือ $ DISPLAY ใช่คุณสามารถใช้คำสั่งส่งออกเพื่อส่งออกตัวแปรบนเชลล์เซสชั่นของคุณหรือ subshells ใด ๆ แต่มันจะหายไปทันทีที่คุณยุติเซสชั่นนั้น
raism
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.