Kabuk - Değişken içerikleri bir dosyaya yaz


98

Bir değişkenin içeriğini (burada denir var) bir dosyaya kopyalamak istiyorum .

Dosyanın adı başka bir değişkende saklanır destfile.

Bunu yaparken sorun yaşıyorum. İşte denediğim şey:

cp $var $destfile

Aynı şeyi dd komutuyla da denedim ... Açıkçası kabuk $varbir dizine atıfta bulunduğunu düşündü ve bu yüzden bana dizinin bulunamadığını söyledi.

Bunu nasıl aşarım?


2
Lütfen değişkenlerinizi nasıl doldurduğunuzu ve ilgili tüm hata mesajlarını tam olarak göründükleri gibi gösteren bazı doğru biçimlendirilmiş kodlar göndererek sorunuzu geliştirin .
Todd A. Jacobs

2
Bir dizine "bir değişkenin içeriğini kopyala" derken neyi kastediyorsunuz? Mu $varbir dosya adı veya bir dosyaya yazılmalıdır bazı metnini belirtmek? Metin belirtiyorsa, bu içeriği yazmak istediğiniz dosyanın adı nedir?
jahroy

$ var kopyalanmak istediğim metni içerir ve yazılması gereken dosya kullanıcı tanımlıdır, bu nedenle ilk etapta bir değişken kullanmamın nedeni budur.
user1546083

1
Belki de yanıltıcı olmayacak $destdirşekilde adlandırılmalı $destfile... Ad $destdir, bir dosya yerine bir dizin belirttiğini gösteriyor. Bu, tüm sorunuzu açık ve anlaşılır hale getirir.
jahroy

Yanıtlar:


150

Şu echokomutu kullanın :

var="text to append";
destdir=/some/directory/path/filename

if [ -f "$destdir" ]
then 
    echo "$var" > "$destdir"
fi

ifTestler $destdirbir dosyayı temsil eder.

>Dosyayı kesiliyor sonra metni ekler. Metni yalnızca $varmevcut içeriğe eklemek istiyorsanız , >>bunun yerine şunu kullanın:

echo "$var" >> "$destdir"

cpKomut değil metni bir dosyaya yazmak için, (dosyalara) dosyalarını kopyalamak için kullanılır.


4
Daha fazla alıntıya ihtiyaç var - şu anda, değişkenin değeri içindeki herhangi bir beyaz boşluk tek bir boşluğa dönüştürülecek, glob ifadeleri genişletilecek, vb.
Charles Duffy

2
Bir başka şey - Eğer kapama tırnağına arasında bir yere ihtiyacım ]in "$destdir"].
Charles Duffy

3
echoayrıca değişkeninize bir satırsonu ekler.
Ben Dilts

6
Bu başarısız $varolduğunu -e text to appendve does't aslında yazma-e
Eric

1
Çünkü echo $varDeğişkeninizi genişletmek için kabuk güvenerek, çalışmıyor çok beyaz boşluk ve özel karakterler gibi şeylerle olacak. Bunun perl -e 'print($ENV{var})'yerine kullanabilirsiniz ve tam olarak değişkenin değerini verir.
Blake Mitchell

41

echovargibi bir şey içeriyorsa -ebir bayrak olarak yorumlanacak problemi var . Diğer bir seçenek ise printf, ancak printf "$var" > "$destdir"değişkendeki herhangi bir çıkış karakterini genişletecektir, bu nedenle değişken ters eğik çizgi içeriyorsa dosya içeriği eşleşmeyecektir. Ancak, printfters eğik çizgileri yalnızca biçim dizesinde kaçış olarak yorumladığından %s, tam değişken içeriğini hedef dosyaya depolamak için biçim belirticisini kullanabilirsiniz :

printf "%s" "$var" > "$destdir"


1
printf, değişken dizede üçlü alıntı veya yorumda olduğu gibi satırsonu satırları varsa da iyidir. echo satırsonlarını iyi idare etmez.
beeflobill

@beeflobill, "echo'nun satırsonlarını iyi idare etmediğini" açıklayabilir misin? Gördüğüm tek şey, echo'nun bir satırsonu eklemesi. Hangi marka yapar echo "$var" > destfileyanlış.
SensorSmith

@SensorSmith Deneylerimde, dizge "\ n" içerdiğinde yankının bir satırsonu karakteri yazdıracağını görüyorum. Ancak, dizge gerçek bir satırsonu karakterine sahipse, yankı onu yazdırmaz. Neden bilmiyorum
beeflobill

1
Temelde bir taşınabilirlik (ve güvenilirlik) sorunu. unix.stackexchange.com/a/65819… veya aramızdaki ölümcül olanlar için: printfdaha iyidir, devam edin.
user3342816

30

Değişkeniniz varsa yukarıdaki yanıtların hiçbiri işe yaramaz:

  • ile başlar -e
  • ile başlar -n
  • ile başlar -E
  • bir ve \ardından birn
  • arkasına fazladan bir satırsonu eklenmemelidir

ve bu nedenle keyfi dizi içerikleri için bunlara güvenilemez.

Bash'de "buradaki dizeleri" şu şekilde kullanabilirsiniz:

cat <<< "$var" > "$destdir"

Aşağıdaki yorumda belirtildiği gibi, @ Trebawa'nın cevabını (benimkiyle aynı odada formüle edilmiştir!) Kullanmak printfdaha iyi bir yaklaşımdır.


5
Söyleyebileceğim kadarıyla, değişkenin sonunda bir satırsonu olmamasına bakılmaksızın, cat her zaman dosyanın sonuna bir satırsonu ekleyecektir (tartışmalı bir şekilde bu çoğu durumda iyi bir şeydir). Cevap kullanarak Printf bir eğik yeni satır ekleme önlemek gibi görünüyor.
Kül

@Ash başka avantajı printfüzerinde cateski daima harici ikili daha hızlı çalıştırır bir kabuk yerleşik olmasıdır.
Géza Török

7

Sizi doğru anladıysam $var, bir dosyaya kopyalamak istersiniz (eğer bir dizeyse).

echo $var > $destdir

Bu nasıl yapılır. cpKomutu kullanmak, kabuğun ilk bağımsız değişkeni bir dosya veya dizinin adı olarak yorumlamasını sağlar.
jahroy

5
Eğer içine Değilse $vartırnak içine, dosyanın içeriği% 100, bazı durumlarda $ var içeriğiyle ile eşit olduğunu. Örneğin, RSA anahtarları içeren değişkenler "yankılanırken", dosyada geçersiz anahtar alırsınız.
srigi

6
$varBoşluk içeriyorsa başarısız olur veya-e
Eric

1

"Bir değişkenin içeriğini kopyala" dediğinizde, bu değişken bir dosya adı mı içeriyor yoksa bir dosya adı mı içeriyor?

Sorunuzun dosyaya kopyalamak istediğiniz içeriği$var içerdiğini varsayıyorum :

$ echo "$var" > "$destdir"

Bu, $ var değerini $ destdir adlı bir dosyaya yansıtır. Alıntılara dikkat edin. Tırnak içinde "$ var" bulunması çok önemlidir. Ayrıca adında boşluk varsa "$ destdir" için. Eklemek için:

$ echo "$var" >> "$destdir"

3
Eğer başarısız variçeren-e
Eric

1
echo Seçenek listesini sonlandırmak için ilk argüman olarak çift kısa çizgi geçmek , böylece @Eric tarafından ortaya atılan sorunu çözer:echo -- "$var" >> "$destfile"
Géza Török

1

Yukarıdakilerin tümü işe yarar, ancak aynı zamanda ilk etapta meydana gelmesi gerekmeyen bir problemi (kaçışlar ve özel karakterler) aşmak zorundadır: Değişken kabuk tarafından genişletildiğinde özel karakterler. Sadece bunu (değişken genişleme) ilk etapta yapmayın. Değişkeni genişletmeden doğrudan kullanın.

Ayrıca, değişkeniniz bir sır içeriyorsa ve bu sırrı bir dosyaya kopyalamak istiyorsanız, kabuk komutlarının izleme / komut yankısı sırrı açığa çıkarabileceği için komut satırında genişletme olmasını istemeyebilirsiniz. Yani, $varkomut satırında kullanılan tüm yanıtlar , değişken içerikleri kabuğun izlenmesine ve günlüğe kaydedilmesine maruz bırakarak potansiyel bir güvenlik riskine sahip olabilir.

Bunu kullan:

printenv var >file

Bu, OP sorusu durumunda:

printenv var >"$destfile"
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.