Bash komut dosyası içinde bir dizeyi komut olarak çalıştırın


156

Komut olarak çalıştırmak için bir dize oluşturan bir Bash betiğim var

Senaryo:

#! /bin/bash

matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/"

teamAComm="`pwd`/a.sh"
teamBComm="`pwd`/b.sh"
include="`pwd`/server_official.conf"
serverbin='/usr/local/bin/rcssserver'

cd $matchdir
illcommando="$serverbin include='$include' server::team_l_start = '${teamAComm}' server::team_r_start = '${teamBComm}' CSVSaver::save='true' CSVSaver::filename = 'out.csv'"

echo "running: $illcommando"
# $illcommando > server-output.log 2> server-error.log
$illcommando

bu argümanları $serverbin.

Komut dosyası çıktısı:

running: /usr/local/bin/rcssserver include='/home/joao/robocup/runner_workdir/server_official.conf' server::team_l_start = '/home/joao/robocup/runner_workdir/a.sh' server::team_r_start = '/home/joao/robocup/runner_workdir/b.sh' CSVSaver::save='true' CSVSaver::filename = 'out.csv'
rcssserver-14.0.1

Copyright (C) 1995, 1996, 1997, 1998, 1999 Electrotechnical Laboratory.
2000 - 2009 RoboCup Soccer Simulator Maintenance Group.


Usage: /usr/local/bin/rcssserver [[-[-]]namespace::option=value]
                                 [[-[-]][namespace::]help]
                                 [[-[-]]include=file]
Options:
    help
        display generic help

    include=file
        parse the specified configuration file.  Configuration files
        have the same format as the command line options. The
        configuration file specified will be parsed before all
        subsequent options.

    server::help
        display detailed help for the "server" module

    player::help
        display detailed help for the "player" module

    CSVSaver::help
        display detailed help for the "CSVSaver" module

CSVSaver Options:
    CSVSaver::save=<on|off|true|false|1|0|>
        If save is on/true, then the saver will attempt to save the
        results to the database.  Otherwise it will do nothing.

        current value: false

    CSVSaver::filename='<STRING>'
        The file to save the results to.  If this file does not
        exist it will be created.  If the file does exist, the results
        will be appended to the end.

        current value: 'out.csv'

sadece komutu yapıştırırsam /usr/local/bin/rcssserver include='/home/joao/robocup/runner_workdir/server_official.conf' server::team_l_start = '/home/joao/robocup/runner_workdir/a.sh' server::team_r_start = '/home/joao/robocup/runner_workdir/b.sh' CSVSaver::save='true' CSVSaver::filename = 'out.csv'("runnning:" sonrasındaki çıktıda) iyi çalışıyor.



Not bazı durumlarda, yapmanız gereken: echo | whateverCommandsyerine sadece whateverCommands(örneğin, böyle yapmak zorunda kaldım: | tail -`echo | whateverCommands`)
Andrew

Yanıtlar:


287

evalBir dizeyi çalıştırmak için kullanabilirsiniz :

eval $illcommando

2
Eval komutun dönüş değerini iletir mi ( dize çıktısı değil, dönüş değeri )?
Tomáš Zato - Monica'yı eski durumuna getir

3
evaltüm programlama dillerinde kötü bir komuttur, bu nedenle dikkatli kullanın.
Krishnadas PC

1
eval "$illcommando", tırnak işaretleriyle birlikte, komutunuzun çalıştırılmadan önce karıştırılmaması. Farkı görmek için tırnak işaretli ve evaltırnaksız bir değer kullanmayı deneyin illcommando='printf "%s\n" " * "'.
Charles Duffy

@ TomášZato-ReinstateMonica Evet, komutun dönüş değerini iletir. Ancak, "${PIPESTATUS[@]}"bash içindeki değişkeni doğru şekilde AYARLAMAZ. Bununla birlikte, komut başarılı bir komuta borulu başarısız bir komut içeriyorsa, bir hata çıkış kodunun döndürülmesine set -o pipefailneden olur eval.
Cameron Hudson

Gibi bir şey yapmaya çalışıyordum grep -E '$filter' unfiltered.txt > filtered.txt, neden komut satırında çalıştığı ve neden hesaplanmış değerlerle bash betiğinde çalışmadığı hakkında hiçbir fikrim yoktu. Cevabınız senaryomu kaydetti. Değerlendirmenin nasıl çalıştığını daha iyi anlamak için kullandığım bazı güzel belgelenmiş örnekleri de buraya ekleyeceğim. linuxhint.com/bash_eval_command
student0495

28

Komutları genellikle parantez içine koyarım $(commandStr), eğer bu bash hata ayıklama modunu harika bulmama yardımcı olmazsa, komut dosyasını şu şekilde çalıştırın:bash -x script


5
CommandStr'ın ne anlama geldiğinden emin değilim, ama en azından bu benim için işe yaramadı. Tam çalışma örnekleri kullanırsanız daha iyi olur.
Robin Manoli

@RobinManoli Sizin için netliği geliştirdi.
Andrew

20
your_command_string="..."
output=$(eval "$your_command_string")
echo "$output"

11

komutlarınızı değişkenlere koymayın, sadece çalıştırın

matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/"
PWD=$(pwd)
teamAComm="$PWD/a.sh"
teamBComm="$PWD/b.sh"
include="$PWD/server_official.conf"
serverbin='/usr/local/bin/rcssserver'    
cd $matchdir
$serverbin include=$include server::team_l_start = ${teamAComm} server::team_r_start=${teamBComm} CSVSaver::save='true' CSVSaver::filename = 'out.csv'

1
sadece bunu yaptı. ama yaptığım tek bir argüman olarak gitmesi gereken değişkenlerim vardı "${arg}". örnek: server :: team_l_start = "$ {teamAComm}"
João Portela

1

./me boost_dead () yayınlar

Bunun gibi bir şey arıyordum, ancak aynı dizeyi eksi iki parametreyi yeniden kullanmam gerekiyordu, bu yüzden şöyle bir şey elde ettim:

my_exe ()
{
    mysql -sN -e "select $1 from heat.stack where heat.stack.name=\"$2\";"
}

Bu, openstack ısı yığını oluşumunu izlemek için kullandığım bir şey. Bu durumda, "Somestack" adlı bir yığın üzerinde "OLUŞTUR" eylemi ve "TAMAMLANDI" durumu olmak üzere iki koşul bekliyorum.

Bu değişkenleri elde etmek için şöyle bir şey yapabilirim:

ACTION=$(my_exe action Somestack)
STATUS=$(my_exe status Somestack)
if [[ "$ACTION" == "CREATE" ]] && [[ "$STATUS" == "COMPLETE" ]]
...

0

Yorumlu metinlerde depolanan dizeleri çalıştıran gradle derleme betiğim :

current_directory=$( realpath "." )
GENERATED=${current_directory}/"GENERATED"
build_gradle=$( realpath build.gradle )

## touch because .gitignore ignores this folder:
touch $GENERATED

COPY_BUILD_FILE=$( cat <<COPY_BUILD_FILE_HEREDOC

    cp 
        $build_gradle 
        $GENERATED/build.gradle

COPY_BUILD_FILE_HEREDOC
)
$COPY_BUILD_FILE

GRADLE_COMMAND=$( cat <<GRADLE_COMMAND_HEREDOC

    gradle run

        --build-file       
            $GENERATED/build.gradle

        --gradle-user-home 
            $GENERATED  

        --no-daemon

GRADLE_COMMAND_HEREDOC
)
$GRADLE_COMMAND

Yalnız ")" biraz çirkin. Ama bu estetik yönü nasıl düzelteceğime dair hiçbir fikrim yok.


0

Komut dosyası tarafından yürütülen tüm komutları görmek için -xbayrağı shabang satırınıza ekleyin ve komutu normal şekilde yürütün:

#! /bin/bash -x

matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/"

teamAComm="`pwd`/a.sh"
teamBComm="`pwd`/b.sh"
include="`pwd`/server_official.conf"
serverbin='/usr/local/bin/rcssserver'

cd $matchdir
$serverbin include="$include" server::team_l_start="${teamAComm}" server::team_r_start="${teamBComm}" CSVSaver::save='true' CSVSaver::filename='out.csv'

Sonra bazen hata ayıklama çıktısını yok saymak istiyorsanız, bir stderryere yönlendirin .


0

Benim echo XYZ_20200824.zip | grep -Eo '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}' için iyi çalışıyordu ancak komut çıktısını değişkene depolayamıyordu. Aynı sorunu denedim evalama çıktı alamadım.

İşte sorunumun cevabı: cmd=$(echo XYZ_20200824.zip | grep -Eo '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}')

echo $cmd

Çıktım şimdi 20200824

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.