GNU/Linux >> Linux Esercitazione >  >> Ubuntu

Sh Alternativa a Bash Cp {file,file}?

In uno script, se metto #!/bin/bash in alto, funzionerà bene:

cp directory/{foo,bar} destination

Tuttavia, con sh, questo darà l'errore "nessun file o directory del genere". In sh, c'è un altro modo per raggiungere lo stesso obiettivo finale con un comando?

Risposta accettata:

Come hai osservato, non tutte le shell supportano l'espansione del rinforzo.

Modo 1:due percorsi separati (ovvero, scrivendo il prefisso due volte)

Se il tuo obiettivo è davvero solo quello di farlo in un comando, un modo semplice è:

cp directory/file1 directory/file2 destination

Il cp comando supporta più argomenti di origine seguiti da un argomento di destinazione. In effetti, questo è ciò che sta accadendo con il comando che funziona per te in Bash. Bash esegue l'espansione delle parentesi, che converte il comando che hai utilizzato in quello mostrato sopra. Cioè, quando esegui cp directory/{file1,file2} destination in Bash, il cp il comando non vede mai parentesi graffe.

Un comando del genere è semplice e di facile comprensione. Suggerisco di prenderlo in considerazione.

Modo 2:una variabile per il prefisso

Ma se il tuo obiettivo è evitare di ripetere te stesso, allora potresti preferire non farlo in quel modo, specialmente se directory in realtà è un lungo percorso. Dopotutto, se devi modificare il percorso più avanti nello script, dovresti apportare modifiche a entrambe le occorrenze.

Puoi memorizzare directory (o qualsiasi altra cosa, presumibilmente un percorso più lungo) in una variabile di shell:

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

$dir è l'espansione dei parametri. La shell lo sostituisce con il valore contenuto nella variabile dir . Quando si utilizza l'espansione dei parametri, non si deve omettere le virgolette doppie, tranne nel raro caso in cui si desidera eseguire la divisione dei campi e il globbing. (Questo vale anche per Bash.)

Sono due comandi, ma se il tuo vero obiettivo è evitare di ripeterti, potrebbe essere quello che vuoi. Potresti scrivere

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

per renderlo "un comando", ma non è più breve ed è un po' meno leggibile.

(Nota che non puoi semplicemente rimuovere il ; là. Il risultato dell'esecuzione sarebbe un comando ben formato, ma non farebbe quello che vuoi. Avrebbe eseguito il cp comando, passando una variabile di ambiente chiamata dir con il valore directory nel cp ambiente del comando. Dal momento che è la shell e non il cp comando, che espande dir , questo non funzionerebbe.)

Modo 3:cd ig al prefisso

Se il tuo script non sta facendo nient'altro dopo aver eseguito questa operazione, o non importa quale sia la directory corrente per i comandi successivi, allora se destination è un percorso assoluto , puoi usare:

cd directory
cp file1 file2 destination

Ma non lo consiglio per lo script a meno che il tuo script non esegua azioni successive che traggono vantaggio dall'essere eseguito da quella directory, o possa essere scritto in modo più conciso o semplicemente quando vengono eseguiti da quella directory. Tranne quando la directory da cui viene eseguito uno script è significativa ai fini del copione, fare affidamento su di esso può rendere più difficile ragionare sul copione; inoltre, se il cd il comando riesce ma il cp comando non riesce, i messaggi di errore risultanti potrebbero non essere completamente illuminati. Cito invece la tecnica di cd ing nella directory di origine perché è un modello utile per interattivo uso della shell.

Correlati:Come installare il driver dell'adattatore wireless TP-Link t2uh (Ralink Mt7610u) in Ubuntu?

(Come ha sottolineato Hannu, puoi racchiudere un numero qualsiasi di comandi insieme all'interno di ( ) per eseguirli in una subshell e modifiche all'ambiente della shell, incluso l'effetto di cd , non persisterà dopo l'esecuzione del comando. Questa è una tecnica ampiamente utile, ed era un'omissione sostanziale che non l'avessi menzionata. Nota, tuttavia, che ciò non attenua i problemi relativi all'avere un percorso relativo per la destination .)

Nota che se il cd comando non riesce, gli altri comandi verranno comunque eseguiti in genere. Questo potrebbe copiare diversi file che non vuoi copiare (se ci sono altri file con lo stesso nome nella directory da cui era in esecuzione lo script) o produrre messaggi di errore confusi. Quindi potresti preferire:

cd directory && cp file1 file2 destination

Il && fa sì che il secondo comando venga eseguito solo se il primo comando è riuscito. Si noti che ciò non annulla ancora l'effetto dell'esecuzione del primo comando. Dopo che l'intera operazione è stata eseguita, sarai ancora nella directory , a meno che tu non l'abbia eseguito in una subshell con ( ) .


Ubuntu
  1. Il comando "eval" in Bash?

  2. a partire da apachectl bash

  3. bash sh - comando non trovato

  4. Bash - Comando data e spazio

  5. Esegui il comando bash sulla pipeline jenkins

Comando della cronologia in Linux (Cronologia di Bash)

Comando di uscita Bash e codici di uscita

Comando Bash printf

comando bat in Linux – alternativa al comando cat

Script Bash(II)

Scripting Bash(III)