Po pierwsze, w mojej obronie: Używam tylko csh, ponieważ moja grupa ma lot ze starszej wersji csh. Wykonujemy programowanie naukowe; niektórzy ludzie najwyraźniej nauczyli się używać csh w czasach SunOS/Solaris i nie poddawali się pomimo przejścia na Linuksa/bash i pomimo (oczywistej) IMHO przewagi tego ostatniego. Po drugie, przepraszam, jeśli jest to najczęściej zadawane pytanie, ale nie znalazłem odpowiedzi za pośrednictwem SO lub ogólnie googlowałem, a ja poświęciłem trochę więcej wysiłku obu.Jak przekazać tablicę numeryczną z bash do csh
takiej sytuacji:
Chcę jechać z bash niektórych starszych CSH skryptów, jako pierwszy krok w kierunku [przepisywanie, usuwając] ten ostatni. bash-> csh działa dobrze dla skalarnych zmiennych środowiskowych ("envvars"), ponieważ mogę je wyeksportować z bashu i odczytać je z csh zgodnie z oczekiwaniami.
Nie tablice, jednak ... poniżej Chris J. Kiick's answer poniżej! Poniższy przykład został zaktualizowany w celu uwzględnienia odpowiedzi Kiick i wyników, które generuje. Umieścić następujące 2 pliki w tym samym katalogu, ...
array_writer.sh
#!/usr/bin/env bash
### Test writing an array, passing it to csh, and reading it there.
THIS="$0"
THIS_DIR="$(readlink -f $(dirname ${THIS}))"
THIS_FN="$(basename ${THIS})"
MESSAGE_PREFIX="${THIS_FN}:"
ERROR_PREFIX="${MESSAGE_PREFIX} ERROR:"
PARTNER_FN='array_reader.csh'
PARTNER_DIR="${THIS_DIR}"
PARTNER_FP="${PARTNER_DIR}/${PARTNER_FN}"
export YEAR='2007'
# month-related arrays for ${YEAR}
declare -a BDOM=(0 31 59 90 120 151 181 212 243 273 304 334) # 0-based-Julian of first day of each month
declare -a MDAY=(31 28 31 30 31 30 31 31 30 31 30 31) # days in each month, length=12
echo -e "${MESSAGE_PREFIX} YEAR='${YEAR}':"
# start debugging
# use subshell for IFS
(IFS=',' ; echo -e "\tBDOM=${BDOM[*]}")
(IFS=',' ; echo -e "\tMDAY=${MDAY[*]}")
# end debugging
### Direct export of arrays fails, but this works!
### Note it actually exports a string: see handling in partner
echo -e "${MESSAGE_PREFIX} about to call ${PARTNER_FP}:\n"
# from https://stackoverflow.com/a/20625229/915044
bdom=${BDOM[*]} mday=${MDAY[*]} ${PARTNER_FP}
if [[ $? -ne 0 ]] ; then
echo -e "\n${ERROR_PREFIX} failed or not found\n"
else
echo -e "\n${MESSAGE_PREFIX} ${PARTNER_FP} returned successfully"
fi
array_reader.csh
#!/bin/csh -f
### Test reading an array written from bash.
set THIS="$0"
# set THISDIR="$(readlink -f $(dirname ${THIS}))" # fails!
set THIS_DIRNAME=`dirname ${THIS}`
set THIS_DIR=`readlink -f ${THIS_DIRNAME}`
set THIS_FN=`basename ${THIS}`
set MESSAGE_PREFIX="${THIS_FN}:"
set ERROR_PREFIX="${MESSAGE_PREFIX} ERROR:"
if ($?bdom) then
# Gotta convert passed string into a "real" csh array
set bdom_array = ($bdom)
echo ${MESSAGE_PREFIX} found export=bdom, size=$#bdom_array":"
printf "\t" # continue on same line
foreach item ($bdom_array)
printf "%d," $item # ditto
end
echo "" # newline to end the array-printing line
else
echo "${ERROR_PREFIX} no export=bdom"
exit 2
endif
echo "" # separate reports
if ($?mday) then
set mday_array = ($mday)
echo ${MESSAGE_PREFIX} found export=mday, size=$#mday_array":"
printf "\t"
foreach item ($mday_array)
printf "%d," $item
end
echo "" # newline to end the array-printing line
else
echo "${ERROR_PREFIX} no export=mday"
exit 3
endif
exit 0
... potem, z muszli, do ...
$ /path/to/array_writer.sh
array_writer.sh: YEAR='2007':
BDOM=0,31,59,90,120,151,181,212,243,273,304,334
MDAY=31,28,31,30,31,30,31,31,30,31,30,31
array_writer.sh: about to call /path/to/array_reader.csh:
array_reader.csh: found export=bdom, size=12:
0,31,59,90,120,151,181,212,243,273,304,334,
array_reader.csh: found export=mday, size=12:
31,28,31,30,31,30,31,31,30,31,30,31,
array_writer.sh: /path/to/array_reader.csh returned successfully
ciekawe pytanie i wyraźnie wydałeś czasu na to, ale czy naprawdę musimy to wszystko ? Czy nie możemy udowodnić problemu w 2-4 linijkach każdego basha i csh? Nie możesz zredukować tego do prostszego przypadku testowego? Powodzenia! – shellter
@shellter to już pomijane ze znacznie większego skryptu, który debuguję, przepraszam. – TomRoche