Как передать аргументы в программу при использовании переменной в качестве пути

Я пытаюсь запустить программу в блоке сценариев Start-job, используя переменную для пути. Вот строка:

$using:plinkdir\plink.exe -telnet $using:ip -P $using:port | TimeStamp >> "$using:LogDir\WeightLog_$(get-date -f MM-dd-yyyy).txt"

Все переменные работают, вся строка работает, когда я использую c:\plink вместо переменной $plink. Он выдает ошибку в -telnet, поэтому не получает аргументы для plink.

Вот $var и работа:

$LogDir = "c:\users\user" # Log file output directory
$PlinkDir = "C:"            # plink.exe directory
$SerialIP = "1.1.1.1"  # serial device IP address
$SerialPort = 10000        # port to log


function CaptureWeight {

  Start-Job -Name WeightLog -ScriptBlock { 

    # Bring Variables into job from callers scope
    #$LogDir = $using:LogDir
    #$PlinkDir = $using:PlinkDir
    #$SerialIP = $using:SerialIP
    #$SerialPort = $using:SerialPort

    # Set TimeStamp format
    filter timestamp {"$(Get-Date -Format MM/dd/yyyy_HH:mm:ss) $_"} 

    # Start plink, pipe output to TimeStamp, redirect to log file
    $using:PlinkDir\plink.exe -telnet $using:SerialIP -P $using:SerialPort | TimeStamp >> "$using:LogDir\WeightLog_$(get-date -f MM-dd-yyyy).txt" 
   }
 }

Спасибо!

Поделитесь всем кодом (определением переменных, а также оператором start-job)

Santiago Squarzon 04.05.2022 23:52

Сообщение @SantiagoSquarzon обновлено, спасибо.

Retrotube 05.05.2022 00:05

Попробуйте вместо этого & "$using:PlinkDir\plink.exe" -telnet... (обратите внимание на двойные кавычки)

Santiago Squarzon 05.05.2022 00:23

Это сработало более или менее после того, как я изменил значение $PlinkDir на «c:\users\user», но добавил пробел между каждым символом и пустую строку между каждой строкой в ​​выводе в файл журнала, интересный результат.

Retrotube 05.05.2022 02:18

Замените TimeStamp >> .. на TimeStamp | Set-Content -Encoding utf8 "$using:LogDi.... ПРИМЕЧАНИЕ. Это заменит существующий файл, если он существует. Если вы хотите добавить к существующему файлу, используйте вместо этого Add-Content

Santiago Squarzon 05.05.2022 02:53

Это помогло решить исходную проблему и проблему с дополнительным интервалом. Это возвращает меня к тому, почему я использовал перенаправление, оно оставляет файл незаблокированным для просмотра. Он не потерял никаких данных, когда powershell неожиданно отключился. Я добираюсь до ОКР, думаю, эта переменная используется только один раз. В настоящее время я думаю, что мой лучший вариант - не использовать переменную для пути к программе. Хотя это так близко к тому, что я хотел. Обновлено: приведенное выше, вероятно, должно быть ответом на этот вопрос, если у вас нет другой идеи для перенаправления.

Retrotube 05.05.2022 03:44
>> это псевдоним для Out-File -Append, немного отличающийся от Set-Content
Santiago Squarzon 05.05.2022 03:56

Две другие вещи крутились у меня в голове, используя Invoke-command, я нашел некоторую информацию об этом и предпочел бы, чтобы это было проще. Другое дело, добавьте plink в среду (путь/переменная?) только для сеанса, чтобы его можно было запустить, например, в блокноте или иначе без пути. Моя формулировка поиска по этому вопросу могла быть ошибочной, поскольку я не мог найти то, что искал.

Retrotube 05.05.2022 04:02

Итак, я понимаю, что вам нужно запустить это в задании, потому что вы хотите убить его в определенное время, пока занимаетесь другими делами, и вы ожидаете, что данные, выводимые plink.exe до того момента, когда задание было уничтожено, будут записаны в файл. Это правильное предположение? И если да, то как вы убиваете работу (используете ли вы Stop-Job)?

Santiago Squarzon 05.05.2022 04:10

Правильно, я упомяну, что «другие вещи» - это просто расчет времени, чем команда ожидания, затем команда остановки, чтобы журнал можно было проанализировать, и он мог начаться снова с новым именем файла даты. Я хочу, чтобы он запустился, ПК загружался и работал до тех пор, пока он работает, может быть месяц или больше. Хотите сделать это только с одной запланированной задачей при загрузке. Я могу сделать все это в настоящее время за вычетом одной переменной для пути к программе. Обновлено: да, просто остановите его с помощью stop-job в сценарии, а затем запустите его снова.

Retrotube 05.05.2022 04:17
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
1
10
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот ответ основан на некоторых предположениях и догадках о том, что может сработать для того, что объяснено в вашем вопросе и комментариях.

Прежде всего, чтобы объяснить «Он не потерял никаких данных, когда PowerShell был неожиданно закрыт»., это потому, что >> (псевдоним для Out-File -Append):

  1. Открытие файлового потока
  2. Добавление вывода в файл
  3. Закрытие потока

Итак, когда вы убиваете задание, то, что есть, все еще там в основном. Я рекомендовал вам использовать Set-Content, но это было до того, как я понял, что вы делаете, в этом случае это был бы не вариант.

Альтернативой, предлагаемой здесь, является использование StreamWriter, что хорошо, потому что мы можем держать файловый поток открытым и добавлять в файл по мере необходимости без необходимости каждый раз закрывать поток (это также позаботится о "пустая строка между каждой строкой в ​​выводе в файл журнала"). Чтобы обойти убивая задание, но сохраняя результаты в файл, мы можем использовать try / finally заявление.

$LogDir     = "c:\users\user" # Log file output directory
$PlinkDir   = "C:"            # plink.exe directory
$SerialIP   = "1.1.1.1"       # serial device IP address
$SerialPort = 10000           # port to log

function CaptureWeight {
    Start-Job -Name WeightLog -ScriptBlock {
        filter timestamp {
            $sw.WriteLine("$(Get-Date -Format MM/dd/yyyy_HH:mm:ss) $_")
        }

        try {
            $sw = [System.IO.StreamWriter]::new("$using:LogDir\WeightLog_$(Get-Date -f MM-dd-yyyy).txt")
            & "$using:PlinkDir\plink.exe" -telnet $using:SerialIP -P $using:SerialPort | TimeStamp
        }
        finally {
            $sw.ForEach('Flush')
            $sw.ForEach('Dispose')
        }
    }
}

$job = CaptureWeight     # For testing, save the job
Start-Sleep -Seconds 60  # wait 1 minute
$job | Stop-Job          # kill the job
Get-Content "$LogDir\WeightLog_$(Get-Date -f MM-dd-yyyy).txt" # Did it work?

Это работает отлично, позволяет использовать переменную для пути к программе, не теряет данные при неожиданном закрытии/сбое, выглядит лучше. Как наблюдение, при попытке просмотреть файл во время его работы кажется, что он обновляется (для просмотра) примерно каждые 2 минуты, вы получаете один 2-минутный фрагмент данных, который отстает примерно на 2 минуты, 2-минутные данные есть . Функционально это совершенно нормально.

Retrotube 05.05.2022 22:54

@Retrotube с удовольствием! Я рад, что это сработало, в основном это было основано на догадках, хе-хе. Рег. "обновление файла" через 2 минуты. Вы можете установить свойство .AutoFlush для $sw на $true, которое должно заботиться об обновлении файла при каждом вызове .WriteLine. Меня сейчас нет дома, трудно редактировать код с телефона. Вы можете задать новый вопрос, и если никто не ответит, я отвечу, когда вернусь.

Santiago Squarzon 05.05.2022 23:13

Спасибо за вашу помощь! собирается запустить это в производство в ближайшее время, чтобы контролировать серийные весы. Это нормально, данные есть, и для целей просмотра 2-минутная задержка в порядке. Я могу поиграть с этой частью больше, если это необходимо.

Retrotube 05.05.2022 23:18

Все еще играл с этим, пытаясь найти лучший способ очистки журналов. Интересно, можно ли игнорировать некоторые строки и не записывать их с самого начала. Похоже, что оператор If может, но не уверен, где его попробовать. Начал новый вопрос здесь: stackoverflow.com/questions/72177600

Retrotube 09.05.2022 22:03

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