GNU/Linux >> Znalost Linux >  >> Ubuntu

Sh Alternativa k Bash Cp {soubor,soubor}?

Pokud do skriptu vložím #!/bin/bash nahoře to bude fungovat dobře:

cp directory/{foo,bar} destination

U sh se však zobrazí chyba „žádný takový soubor nebo adresář“. Existuje v sh jiný způsob, jak dosáhnout stejného konečného cíle jedním příkazem?

Přijatá odpověď:

Jak jste si všimli, ne všechny skořepiny podporují expanzi vzpěry.

Způsob 1:Dvě samostatné cesty (tj. zapsání předpony dvakrát)

Pokud je vaším cílem opravdu to udělat jedním příkazem, jednoduchý způsob je:

cp directory/file1 directory/file2 destination

cp příkaz podporuje více zdrojových argumentů následovaných argumentem cíle. Ve skutečnosti se to děje s příkazem, který pro vás funguje v Bash. Bash provede rozšíření složené závorky, které převede příkaz, který jste používali, na příkaz uvedený výše. To znamená, že když spustíte cp directory/{file1,file2} destination v Bash, cp příkaz nikdy nevidí žádné složené závorky.

Takový příkaz je jednoduchý a snadno pochopitelný. Navrhuji to zvážit.

Způsob 2:Proměnná pro prefix

Ale pokud je vaším cílem vyhnout se opakování vy, pak to možná raději neuděláte tímto způsobem, zvláště pokud jde o directory je vlastně dlouhá cesta. Pokud byste totiž museli později ve skriptu upravit cestu, museli byste provést změny v obou výskytech.

Můžete uložit directory (nebo cokoli, pravděpodobně delší cesta) v proměnné shellu:

dir='directory'
cp "$dir/file1" "$dir/file2" destination

$dir je rozšíření parametrů. Shell jej nahradí hodnotou uloženou v proměnné dir . Při použití rozšíření parametrů byste neměli vynechat dvojité uvozovky – kromě výjimečného případu, kdy chcete, aby se provedlo dělení polí a globování. (To platí i pro Bash.)

To jsou dva příkazy, ale pokud je vaším skutečným cílem vyhnout se opakování, může to být to, co chcete. Mohl bys napsat

dir='directory'; cp "$dir/file1" "$dir/file2" destination

aby to bylo „jeden příkaz“, ale není to kratší a je to o něco méně čitelné.

(Všimněte si, že nemůžete jednoduše odstranit ; tam. Výsledkem by byl dobře vytvořený příkaz, ale nedělal by to, co chcete. Spustilo by to cp předá proměnnou prostředí nazvanou dir s hodnotou directory do cp prostředí příkazu. Protože je to shell a ne cp příkaz, který rozšiřuje dir , to by nefungovalo.)

Způsob 3:cd ig na předponu

Pokud váš skript po provedení této operace nedělá nic jiného nebo nezáleží na tom, jaký je aktuální adresář pro následující příkazy, pak if destination je absolutní cesta , můžete použít:

cd directory
cp file1 file2 destination

Ale nedoporučuji to pro skriptování, pokud váš skript neprovádí následné akce, které těží z toho, že jsou spouštěny z tohoto adresáře, nebo pokud je nelze zapsat stručněji nebo jednodušeji, když jsou spouštěny z tohoto adresáře. Kromě případů, kdy je adresář, ze kterého je skript spouštěn, smysluplný Pokud jde o účel scénáře, spoléhání se na něj může ztížit uvažování o scénáři; dále pokud cd příkaz uspěje, ale cp příkaz selže, výsledné chybové zprávy mohou být méně než plně svítivé. Místo toho zmiňuji techniku ​​cd do zdrojového adresáře, protože je to užitečný vzor pro interaktivní použití shellu.

Související:Jak nainstalovat ovladač bezdrátového adaptéru TP-Link t2uh (Ralink Mt7610u) v Ubuntu?

(Jak zdůraznil Hannu, do () můžete uzavřít libovolný počet příkazů dohromady ) jejich spouštění v podshellu a změny prostředí prostředí, včetně efektu cd , nebude po spuštění příkazu přetrvávat. Toto je široce užitečná technika a bylo podstatné opomenutí, že jsem ji nezmínil. Upozorňujeme však, že to nezmírňuje žádné problémy související s relativní cestou pro destination .)

Všimněte si, že pokud cd příkaz selže, ostatní příkazy se stále obvykle spustí. Mohlo by to zkopírovat různé soubory, které kopírovat nechcete (pokud jsou v adresáři, ze kterého byl skript spuštěn, další soubory se stejnými názvy) nebo způsobit matoucí chybové zprávy. Můžete tedy preferovat:

cd directory && cp file1 file2 destination

&& způsobí spuštění druhého příkazu pouze v případě, že první příkaz uspěl. Všimněte si, že to stále nezruší účinek spuštění prvního příkazu. Po spuštění celé věci budete stále v directory , pokud jste jej nespustili v podshellu s ( ) .


Ubuntu
  1. spouštění apachectl z bash

  2. příkaz pro export bash

  3. Spusťte příkaz bash na jenkins pipeline

  1. Příkaz „eval“ v Bash?

  2. bash sh - příkaz nenalezen

  3. Bash, pokud na jednom řádku

  1. Bash wait Příkaz s příklady

  2. Vysvětlení příkazu Bash trap

  3. Bash - příkaz Datum a mezera