`Kaynak` komutunun tersi


9

sourceDeğişken değerlerini okumak / yazdırmak için bash komut dosyamdaki komutu kullanıyorum

more linuxmachines_mount_point.txt

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"

source  linuxmachines_mount_point.txt

echo $linuxmachine01
sdb sdc sdf sdd sde sdg

sourceDeğişkenleri çözmek için bunun tam tersi nedir ?

Beklenen sonuçlar

echo $linuxmachine01

< no output >

14
sourceOrtamınızdaki değişkenleri ayarlamak değil export, dosyadaki ifadeleri ayarlamaktır source. Yani tam tersi sourceolabilir source, eğer aynı değişkenlere sourcesahip farklı bir unsetdosyaysanız.
user4556274

2
yael, verme, sadece name = "val" kullanın. Dışa aktarma komut dosyası-ikili değişkenler (ortam) içindir.
ctrl-d


2
Bu imkansız. Aradığınız konsepte Tersinir Hesaplama denir . Programlama dillerinin geri döndürülebilir olması için bazı ciddi kısıtlamalarla özel olarak tasarlanması gerekir . Bash bu programlama dillerinden biri değil.
Jörg W Mittag

1
@yael, bu doğru değil (ve açıkça ctrl-d'ye yapmasını söylediğin testi hiç çalıştırmadın); kesinlikle exports'ye ihtiyacınız yok . Tüm exportbunlar, değerleri ortama kopyalamaktır - ancak ortam değişkenleri olarak tanımlanıp tanımlanmadıklarına bakılmaksızın kabuk değişkenleri olarak bulunurlar. Ayrıca, gereksiz ortam değişkenlerinin tanımlanması, işlem başına aynı alanda (sınırlı!) Depolandıkları için maksimum komut satırı uzunluğunuzu kısaltır.
Charles Duffy

Yanıtlar:


21

Alt kabuk kullanma (Önerilir)

Bir alt kabukta source komutunu çalıştırın:

(
source linuxmachines_mount_point.txt
cmd1 $linuxmachine02
other_commands_using_variables
etc
)
echo $linuxmachine01  # Will return nothing

Altkabuklarda Pars tanımlanır: (...). Alt kabuk sona erdiğinde ayarlanmış olan kabuk değişkenleri unutulur.

Unset kullanma

Bu, aşağıdakiler tarafından dışa aktarılan tüm değişkenleri sıfırlar linuxmachines_mount_point.txt:

unset $(awk -F'[ =]+' '/^export/{print $2}' linuxmachines_mount_point.txt)
  • -F'[ =]+' awk'ye alan ayırıcısı olarak herhangi bir boşluk ve eşit işaret kombinasyonunu kullanmasını söyler.

  • /^export/{print $2}

    Bu awk ile başlayan satırları seçip exportikinci alanı yazdırmasını söyler .

  • unset $(...)

    Bu, içindeki komutu çalıştırır, $(...)stdout'unu yakalar ve çıktısı tarafından adlandırılan değişkenleri kaldırır.


neden kullanmıyorsunuz - i için `` awk '{print $ 2}' dosyasında | awk -F "=" '{print $ 1}' '; $ i ayarını kaldır; bitti mi? (unset için daha basit)
yael

2
@yael İkisine de gerek olmadığında fazladan bir işlem ve döngü kullanır. Görüşler değişebilir, ancak bunu daha basit görmüyorum. Ayrıca ve potansiyel olarak tehlikeli olan, her satırın filebir ihracat beyanı olduğunu varsayar .
John1024

8
@yael Ayrıca, değişkenlerin ayarlanması ve diğer kod yan etkilerinin geri alınması, alt kabukların tam olarak ne olduğudur. Bunu basit ve güvenilir bir şekilde yaparlar. Aksi takdirde özel bir neden olmadığı sürece, alt kabuklar kullanmanız gereken şeydir.
John1024

4

sourceBetiğin ununu kaldıramazsınız .

Yapabileceğiniz şey, dışa aktarılan tüm değişkenleri geçici bir dosyada saklamak, komut dosyası kaynaklandıktan sonra değişkenlerle karşılaştırmak ve daha sonra taşması kaldırmaktır unset, örneğin:

export > temp_file
source myscript

#... do some stuff

unset "$(comm -3 <(sort temp_file) <(export | sort) | awk -F'[ =]' '{print $3}' | tr '\n' ' ')"

neden kullanmıyorsunuz - i için `` awk '{print $ 2}' dosyasında | awk -F "=" '{print $ 1}' '; $ i ayarını kaldır; bitti mi? (unset için daha basit)
yael

@yael yalnızca komut dosyası yalnızca exports içeriyorsa çalışır .
jimmij

ne demek "ihracat s", benim dosya içerir linuxmachine01 = "sdb sdc sdf sdd sde sdg" ve böylece, ve ben awk döngü kullandığımda onun unset değişkeni sorunsuz
yael aralık

@yael Dosyanızın tam olarak nasıl göründüğünü bilmiyorum, bu yüzden genel bir cevap verdim, örneğin komut dosyasının üst kısmında "# Bağlama noktaları ile dışa aktarmak için bazı değişkenler" diyerek bir yorum varsa.
jimmij

2

unsetDeğişkenleri "unutmak" için komutu kullanabilirsiniz .


dosya diff makineleri ile olabilir, bu yüzden dosyadaki ikinci değişkenler nasıl ayarlanır?
yael

unset variablename onu unutacak (bash / sh / ksh / zsh man sayfasında açıklanmış bulabilirsiniz) demosu: pastebin.com/MGQyTZEA
francois P

Evet, ancak değişkenler farklı olabileceğinden, bash betiği değişkenin dosyadan okunması ve bunların
ayarlarının kaldırılmasıyla

daha sonra dışa aktarılacak satırları (kesim) dosyadaki değişkenleri ayarlanamayacak şekilde listelemek için dışa aktarın ihracat linuxmachine06 = "sdb sde sdf sdd" o zaman burada ayarlanmamış komutun adını gördüğünüz gibi linuxmachine06 alırsınız: pastebin.com/M9eCtLc7 sadece sonunda bilindiği değişken adını bilmiyorum
francois P

Tamam Bu sözdizimini ayarlamak için kullanacağım - `` awk '{print $ 2}' dosyasındaki i için | awk -F "=" '{print $ 1}' '; $ i ayarını kaldır; tamamlandı
yael

2

Beklediğiniz çıktıya sahip olmanın en basit çözümü (hiçbir şey) değişkeni boş olarak yeniden bildirmektir:

$ export linuxmachine01="sdb sdc sdf sdd sde sdg"
$ echo "$linuxmachine01"
sdb sdc sdf sdd sde sdg

$ linuxmachine01=""
$ echo "$linuxmachine01"
$

Tabii ki değişken hala tanımlanmış (ve dışa aktarılmış), boş ama tanımlanmış:

$ declare -p linuxmachine01
declare -x linuxmachine01=""

Değişkeni hem ortamdan hem de çalışan kabuktan doğru bir şekilde çıkarmak için unset (önerilen yol) kullanmalısınız:

$ unset linuxmachine01
$ declare -p linuxmachine01
bash: declare: linuxmachine01: not found
$ echo "$linuxmachine01"
$

1

Bunu yapmanın en basit yolu, komut dosyanızı değiştirmek ve komut dosyasının etkisini geri almak için bir komut tanımlamaktır:

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"
alias linuxmachines_mount_point='for v in linuxmachine01 linuxmachine02 linuxmachine03 linuxmachine04; do unset $v; done; unalias linuxmachines_mount_point'

Neden bir işlev yerine bir takma ad? Takma adların etkileşimsiz kabuklarda varsayılan olarak devre dışı bırakıldığını unutmayın, bu nedenle kullanıma hazırdır, bu bir komut dosyasında çalışmaz.
Charles Duffy

Belirlediğimiz eğer ... Aslında bu da kolay olurdu sadece bir değişken ve böylece tek bir unset zorunda kaldı: declare -A linuxmachines=( [01]="sdb sdc sdf" [02]="sde sdd sdb" [03]="whatever" )o zaman sadece var unset linuxmachines, geri almadan etmek.
Charles Duffy

@CharlesDuffy: hem takma ad hem de işlev bu amaç için uygundur. Her şeyi bir değişkene koymayı önermememin nedeni, geri alma komutunu tanımlamanın çok daha genel olmasıdır. Sadece değişkenleri değil aynı zamanda fonksiyonları, takma adları, sistem ayarlarını, terminal ayarlarını vb. De tanımlayabilirsiniz.
Yalan Ryan

Yukarıdaki amacım, "amaç" etkileşimli olmayan kullanım (yani komut dosyalarından çağırma) içeriyorsa takma adların amaç için iyi olmadığına inanıyorum .
Charles Duffy

0

Linuxmachines_mount_point.txt'nizi şöyle yazabilirsiniz

test "$linuxmachine01" && unset -v linuxmachine01 || linuxmachine01="sdb sdc sdf sdd sde sdg"

Değişkenlerinize ihtiyacınız olduğunda

source linuxmachines_mount_point.txt

Değişkenleri kaldırmak istediğinizde

source linuxmachines_mount_point.txt

0

A'yı sourceetkinleştirmek VirtualEnvironmentiçin komutu kullanıyorsanız, komutu kullanarak çıkabilirsiniz deactivate.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.