Переключить перенаправление Bash с переменной

Спасибо всем, кто ответил, вы очень помогли мне в понимании bash-скриптов, теперь, когда этот вопрос решен, как можно было бы закрыть вопрос?

Я использовал скрипт предоставленный John1024, работал безупречно. Очень уместно для этого. Приветствия

! / Bin / sh

cd "$ 1" || {echo "Не удалось записать cd в каталог $ 1. Выход." ; выход 1; } для fname в * .txt do awk 'NR% 2 == 1 {print; } '"$ fname"> "$ {fname% .txt} .bat" done

1
задан 16 March 2016 в 03:25

3 ответа

Из справочного руководства Bash: Простое расширение команды:

Слова, которые синтаксический анализатор помечен как переменные назначения (те, которые предшествуют имени команды) и перенаправления, сохраняются для последующей обработки. Слова, которые не являются переменными назначениями или перенаправлением, расширяются (см. Раздел «Расширения оболочки»). Если после расширения слова остаются какие-либо слова, первое слово считается именем команды, а остальные слова являются аргументами. Перенаправления выполняются, как описано выше (см. Раздел «Направления»).

Это означает, что синтаксический анализатор команд сначала идентифицирует все переадресации, затем выполняет различные расширения и, наконец, разрешает перенаправления, которые он ранее идентифицировал: они не включают возможные перенаправления, возникающие в результате расширений.

Однако из help eval:

Execute arguments as a shell command.

    Combine ARGs into a single string, use the result as input to the shell,
    and execute the resulting commands.

Таким образом, используя eval, вы можете создать своего рода уровень косвенности, который позволит обрабатывать команду дважды: [!d10 ]

MUTE='&> /dev/null'
eval echo "text" $MUTE
$ MUTE='&> file'
$ eval echo "text" $MUTE
$ cat file
text
3
ответ дан 23 May 2018 в 12:49

Можно использовать функцию, которая записывает свой stdin туда, где вы хотите.

$> MUTE(){  cat /dev/stdin > testFile.txt  ; }                                                    
$> df | MUTE                                                                                      
$> cat testFile.txt
Filesystem     1K-blocks     Used Available Use% Mounted on
udev             1954208        4   1954204   1% /dev
tmpfs             393160     3548    389612   1% /run
/dev/sda1      115247656 95511252  13859056  88% /
none                   4        0         4   0% /sys/fs/cgroup
none                5120        0      5120   0% /run/lock
none             1965792      872   1964920   1% /run/shm
none              102400      128    102272   1% /run/user
cgmfs                100        0       100   0% /run/cgmanager/fs

Или мы могли бы сказать, что функция выполняет все, что захочет, с перенаправлением

$> MUTE(){  "$@" > testFile.txt  ; }                                                              
$> MUTE lsblk                                                                                     
$> cat testFile.txt                                                                               
NAME                             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                                8:0    0 111.8G  0 disk 
└─sda1                             8:1    0 111.8G  0 part /

Нестандартный способ, хакерство, но это вроде работы:)

2
ответ дан 23 May 2018 в 12:49

Он работает таким образом, я не знаю, подходит ли он для вашего подхода:

MUTE='&> /dev/null'
bash -c "echo \"text\" $MUTE"
1
ответ дан 23 May 2018 в 12:49

Другие вопросы по тегам:

Похожие вопросы: